refactor code & add HeanCms source
This commit is contained in:
parent
cd20e55e62
commit
d23624c39b
44 changed files with 714 additions and 386 deletions
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
|
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"java.configuration.updateBuildConfiguration": "automatic"
|
||||
"java.configuration.updateBuildConfiguration": "automatic",
|
||||
"githubPullRequests.ignoredPullRequestBranches": [
|
||||
"main"
|
||||
]
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ class SourceModel extends HiveObject {
|
|||
@HiveField(0)
|
||||
final String sourceName;
|
||||
@HiveField(1)
|
||||
final String url;
|
||||
final String baseUrl;
|
||||
@HiveField(2)
|
||||
final String lang;
|
||||
@HiveField(3, defaultValue: true)
|
||||
|
|
@ -28,10 +28,11 @@ class SourceModel extends HiveObject {
|
|||
final String dateFormat;
|
||||
@HiveField(11)
|
||||
final String dateFormatLocale;
|
||||
|
||||
@HiveField(12)
|
||||
final String apiUrl;
|
||||
SourceModel({
|
||||
required this.sourceName,
|
||||
required this.url,
|
||||
required this.baseUrl,
|
||||
required this.lang,
|
||||
required this.typeSource,
|
||||
required this.logoUrl,
|
||||
|
|
@ -42,6 +43,7 @@ class SourceModel extends HiveObject {
|
|||
this.isNsfw = false,
|
||||
this.isFullData = false,
|
||||
this.isCloudflare = false,
|
||||
this.apiUrl = "",
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -54,5 +56,7 @@ enum TypeSource {
|
|||
@HiveField(3)
|
||||
comick,
|
||||
@HiveField(4)
|
||||
mmrcms
|
||||
mmrcms,
|
||||
@HiveField(5)
|
||||
heancms
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class SourceModelAdapter extends TypeAdapter<SourceModel> {
|
|||
};
|
||||
return SourceModel(
|
||||
sourceName: fields[0] as String,
|
||||
url: fields[1] as String,
|
||||
baseUrl: fields[1] as String,
|
||||
lang: fields[2] as String,
|
||||
typeSource: fields[6] as TypeSource,
|
||||
logoUrl: fields[7] as String,
|
||||
|
|
@ -29,17 +29,18 @@ class SourceModelAdapter extends TypeAdapter<SourceModel> {
|
|||
isNsfw: fields[5] == null ? false : fields[5] as bool,
|
||||
isFullData: fields[8] == null ? false : fields[8] as bool,
|
||||
isCloudflare: fields[9] == null ? false : fields[9] as bool,
|
||||
apiUrl: fields[12] as String,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SourceModel obj) {
|
||||
writer
|
||||
..writeByte(12)
|
||||
..writeByte(13)
|
||||
..writeByte(0)
|
||||
..write(obj.sourceName)
|
||||
..writeByte(1)
|
||||
..write(obj.url)
|
||||
..write(obj.baseUrl)
|
||||
..writeByte(2)
|
||||
..write(obj.lang)
|
||||
..writeByte(3)
|
||||
|
|
@ -59,7 +60,9 @@ class SourceModelAdapter extends TypeAdapter<SourceModel> {
|
|||
..writeByte(10)
|
||||
..write(obj.dateFormat)
|
||||
..writeByte(11)
|
||||
..write(obj.dateFormatLocale);
|
||||
..write(obj.dateFormatLocale)
|
||||
..writeByte(12)
|
||||
..write(obj.apiUrl);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -88,6 +91,8 @@ class TypeSourceAdapter extends TypeAdapter<TypeSource> {
|
|||
return TypeSource.comick;
|
||||
case 4:
|
||||
return TypeSource.mmrcms;
|
||||
case 5:
|
||||
return TypeSource.heancms;
|
||||
default:
|
||||
return TypeSource.single;
|
||||
}
|
||||
|
|
@ -108,6 +113,9 @@ class TypeSourceAdapter extends TypeAdapter<TypeSource> {
|
|||
case TypeSource.mmrcms:
|
||||
writer.writeByte(4);
|
||||
break;
|
||||
case TypeSource.heancms:
|
||||
writer.writeByte(5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ import 'package:mangayomi/models/chapter.dart';
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/providers/hive_provider.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.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';
|
||||
import 'package:mangayomi/sources/src/multi/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
|
||||
|
|
@ -49,7 +50,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
/*comick*/
|
||||
/********/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.comick) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
pageUrls = await Comick().getMangaChapterUrl(chapter: chapter);
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +58,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
/*mangathemesia*/
|
||||
/**************/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
pageUrls = await MangaThemeSia().getMangaChapterUrl(chapter: chapter);
|
||||
}
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
/*mmrcms*/
|
||||
/***********/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.mmrcms) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
pageUrls = await Mmrcms().getMangaChapterUrl(chapter: chapter);
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +94,14 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
pageUrls = await Japscan().getMangaChapterUrl(chapter: chapter);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*heancms*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
pageUrls = await HeanCms().getMangaChapterUrl(chapter: chapter);
|
||||
}
|
||||
|
||||
if (pageUrls.isNotEmpty) {
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaProvider).put(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'get_manga_chapter_url.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getMangaChapterUrlHash() =>
|
||||
r'4daf1dc296255c64ca0ee2cf963dd98b3595d93c';
|
||||
r'066c4d826fd17ba3d3682d806778fe1010378c05';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,64 +1,63 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.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';
|
||||
import 'package:mangayomi/sources/src/multi/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_manga_detail.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga> getMangaDetail(GetMangaDetailRef ref,
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
GetMangaDetailModel? mangadetail;
|
||||
GetManga? mangadetail;
|
||||
|
||||
/********/
|
||||
/*comick*/
|
||||
/********/
|
||||
|
||||
if (getWpMangTypeSource(source.toLowerCase()) == TypeSource.comick) {
|
||||
mangadetail = await Comick().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
if (getMangaTypeSource(source.toLowerCase()) == TypeSource.comick) {
|
||||
mangadetail =
|
||||
await Comick().getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
/*************/
|
||||
/*mangathemesia*/
|
||||
/**************/
|
||||
|
||||
if (getWpMangTypeSource(source.toLowerCase()) == TypeSource.mangathemesia) {
|
||||
mangadetail = await MangaThemeSia().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
if (getMangaTypeSource(source.toLowerCase()) == TypeSource.mangathemesia) {
|
||||
mangadetail = await MangaThemeSia()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
/***********/
|
||||
/*mangakawaii*/
|
||||
/***********/
|
||||
else if (source.toLowerCase() == "mangakawaii") {
|
||||
mangadetail = await MangaKawaii().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
mangadetail = await MangaKawaii()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mmrcms*/
|
||||
/***********/
|
||||
|
||||
else if (getWpMangTypeSource(source.toLowerCase()) == TypeSource.mmrcms) {
|
||||
mangadetail = await Mmrcms().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
else if (getMangaTypeSource(source.toLowerCase()) == TypeSource.mmrcms) {
|
||||
mangadetail =
|
||||
await Mmrcms().getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*mangahere*/
|
||||
/***********/
|
||||
else if (source.toLowerCase() == "mangahere") {
|
||||
mangadetail = await Mangahere().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
mangadetail = await Mangahere()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -66,8 +65,17 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
|||
/***********/
|
||||
|
||||
else if (source.toLowerCase() == "japscan") {
|
||||
mangadetail = await Japscan().getMangaDetail(
|
||||
imageUrl: imageUrl, url: url, title: title, lang: lang, source: source);
|
||||
mangadetail = await Japscan()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*heancms*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source.toLowerCase()) == TypeSource.heancms) {
|
||||
mangadetail = await HeanCms()
|
||||
.getMangaDetail(manga: manga, lang: lang, source: source);
|
||||
}
|
||||
return mangadetail!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_manga_detail.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getMangaDetailHash() => r'989fdfaf80bf546d1f9910b0715afc9a0e64f33a';
|
||||
String _$getMangaDetailHash() => r'ee4c8c5203a9cc0d6de3697f96e5e46e80218fc2';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -29,29 +29,25 @@ class _SystemHash {
|
|||
}
|
||||
}
|
||||
|
||||
typedef GetMangaDetailRef = AutoDisposeFutureProviderRef<GetMangaDetailModel>;
|
||||
typedef GetMangaDetailRef = AutoDisposeFutureProviderRef<GetManga>;
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
@ProviderFor(getMangaDetail)
|
||||
const getMangaDetailProvider = GetMangaDetailFamily();
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
class GetMangaDetailFamily extends Family<AsyncValue<GetMangaDetailModel>> {
|
||||
class GetMangaDetailFamily extends Family<AsyncValue<GetManga>> {
|
||||
/// See also [getMangaDetail].
|
||||
const GetMangaDetailFamily();
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
GetMangaDetailProvider call({
|
||||
required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
required GetManga manga,
|
||||
required String lang,
|
||||
required String source,
|
||||
}) {
|
||||
return GetMangaDetailProvider(
|
||||
imageUrl: imageUrl,
|
||||
url: url,
|
||||
title: title,
|
||||
manga: manga,
|
||||
lang: lang,
|
||||
source: source,
|
||||
);
|
||||
|
|
@ -62,9 +58,7 @@ class GetMangaDetailFamily extends Family<AsyncValue<GetMangaDetailModel>> {
|
|||
covariant GetMangaDetailProvider provider,
|
||||
) {
|
||||
return call(
|
||||
imageUrl: provider.imageUrl,
|
||||
url: provider.url,
|
||||
title: provider.title,
|
||||
manga: provider.manga,
|
||||
lang: provider.lang,
|
||||
source: provider.source,
|
||||
);
|
||||
|
|
@ -86,21 +80,16 @@ class GetMangaDetailFamily extends Family<AsyncValue<GetMangaDetailModel>> {
|
|||
}
|
||||
|
||||
/// See also [getMangaDetail].
|
||||
class GetMangaDetailProvider
|
||||
extends AutoDisposeFutureProvider<GetMangaDetailModel> {
|
||||
class GetMangaDetailProvider extends AutoDisposeFutureProvider<GetManga> {
|
||||
/// See also [getMangaDetail].
|
||||
GetMangaDetailProvider({
|
||||
required this.imageUrl,
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.manga,
|
||||
required this.lang,
|
||||
required this.source,
|
||||
}) : super.internal(
|
||||
(ref) => getMangaDetail(
|
||||
ref,
|
||||
imageUrl: imageUrl,
|
||||
url: url,
|
||||
title: title,
|
||||
manga: manga,
|
||||
lang: lang,
|
||||
source: source,
|
||||
),
|
||||
|
|
@ -115,18 +104,14 @@ class GetMangaDetailProvider
|
|||
GetMangaDetailFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final String imageUrl;
|
||||
final String url;
|
||||
final String title;
|
||||
final GetManga manga;
|
||||
final String lang;
|
||||
final String source;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is GetMangaDetailProvider &&
|
||||
other.imageUrl == imageUrl &&
|
||||
other.url == url &&
|
||||
other.title == title &&
|
||||
other.manga == manga &&
|
||||
other.lang == lang &&
|
||||
other.source == source;
|
||||
}
|
||||
|
|
@ -134,9 +119,7 @@ class GetMangaDetailProvider
|
|||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, imageUrl.hashCode);
|
||||
hash = _SystemHash.combine(hash, url.hashCode);
|
||||
hash = _SystemHash.combine(hash, title.hashCode);
|
||||
hash = _SystemHash.combine(hash, manga.hashCode);
|
||||
hash = _SystemHash.combine(hash, lang.hashCode);
|
||||
hash = _SystemHash.combine(hash, source.hashCode);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,33 +1,34 @@
|
|||
import 'dart:async';
|
||||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.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';
|
||||
import 'package:mangayomi/sources/src/multi/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_popular_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
||||
Future<List<GetManga?>> getPopularManga(GetPopularMangaRef ref,
|
||||
{required String source, required int page}) async {
|
||||
GetMangaModel? popularManga;
|
||||
List<GetManga?>? popularManga;
|
||||
source = source.toLowerCase();
|
||||
|
||||
/*********/
|
||||
/*comick*/
|
||||
/*******/
|
||||
if (getWpMangTypeSource(source) == TypeSource.comick) {
|
||||
if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
popularManga = await Comick().getPopularManga(source: source, page: page);
|
||||
}
|
||||
|
||||
/***************/
|
||||
/*mangathemesia*/
|
||||
/**************/
|
||||
if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||
if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
popularManga =
|
||||
await MangaThemeSia().getPopularManga(source: source, page: page);
|
||||
}
|
||||
|
|
@ -44,7 +45,7 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
|||
/*mmrcms*/
|
||||
/***********/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.mmrcms) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
popularManga = await Mmrcms().getPopularManga(source: source, page: page);
|
||||
}
|
||||
|
||||
|
|
@ -61,5 +62,12 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
|||
else if (source == "japscan") {
|
||||
popularManga = await Japscan().getPopularManga(source: source, page: page);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*japscan*/
|
||||
/***********/
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
popularManga = await HeanCms().getPopularManga(source: source, page: page);
|
||||
}
|
||||
return popularManga!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_popular_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getPopularMangaHash() => r'cec4ced8864aca6f08b29a8ef9405fd21b68927f';
|
||||
String _$getPopularMangaHash() => r'0571fdcea7fc7aebb97c5748f6781e4075705382';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -29,14 +29,14 @@ class _SystemHash {
|
|||
}
|
||||
}
|
||||
|
||||
typedef GetPopularMangaRef = AutoDisposeFutureProviderRef<GetMangaModel>;
|
||||
typedef GetPopularMangaRef = AutoDisposeFutureProviderRef<List<GetManga?>>;
|
||||
|
||||
/// See also [getPopularManga].
|
||||
@ProviderFor(getPopularManga)
|
||||
const getPopularMangaProvider = GetPopularMangaFamily();
|
||||
|
||||
/// See also [getPopularManga].
|
||||
class GetPopularMangaFamily extends Family<AsyncValue<GetMangaModel>> {
|
||||
class GetPopularMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
||||
/// See also [getPopularManga].
|
||||
const GetPopularMangaFamily();
|
||||
|
||||
|
|
@ -77,7 +77,8 @@ class GetPopularMangaFamily extends Family<AsyncValue<GetMangaModel>> {
|
|||
}
|
||||
|
||||
/// See also [getPopularManga].
|
||||
class GetPopularMangaProvider extends AutoDisposeFutureProvider<GetMangaModel> {
|
||||
class GetPopularMangaProvider
|
||||
extends AutoDisposeFutureProvider<List<GetManga?>> {
|
||||
/// See also [getPopularManga].
|
||||
GetPopularMangaProvider({
|
||||
required this.source,
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@ import 'package:http/http.dart' as http;
|
|||
|
||||
Future<Document> httpResToDom(
|
||||
{required String url, required Map<String, String>? headers}) async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(url), headers: headers);
|
||||
return Document.html(response.body);
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await http.get(Uri.parse(url), headers: headers);
|
||||
return Document.html(response.body);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,27 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/heancms.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/comick.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';
|
||||
import 'package:mangayomi/sources/src/multi/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/src/mangathemesia.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mmrcms/src/mmrcms.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'search_manga.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future<GetMangaModel> searchManga(SearchMangaRef ref,
|
||||
Future<List<GetManga?>> searchManga(SearchMangaRef ref,
|
||||
{required String source, required String query}) async {
|
||||
GetMangaModel? manga;
|
||||
List<GetManga?>? manga;
|
||||
source = source.toLowerCase();
|
||||
|
||||
/********/
|
||||
/*comick*/
|
||||
/********/
|
||||
|
||||
if (getWpMangTypeSource(source) == TypeSource.comick) {
|
||||
if (getMangaTypeSource(source) == TypeSource.comick) {
|
||||
manga = await Comick().searchManga(source: source, query: query);
|
||||
}
|
||||
|
||||
|
|
@ -28,10 +29,10 @@ Future<GetMangaModel> searchManga(SearchMangaRef ref,
|
|||
/*mangathemesia*/
|
||||
/***************/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.mangathemesia) {
|
||||
manga = await MangaThemeSia().searchManga(source: source, query: query);
|
||||
}
|
||||
|
||||
|
||||
/***********/
|
||||
/*mangakawaii*/
|
||||
/***********/
|
||||
|
|
@ -44,10 +45,10 @@ Future<GetMangaModel> searchManga(SearchMangaRef ref,
|
|||
/*mmrcms*/
|
||||
/***********/
|
||||
|
||||
else if (getWpMangTypeSource(source) == TypeSource.mmrcms) {
|
||||
else if (getMangaTypeSource(source) == TypeSource.mmrcms) {
|
||||
manga = await Mmrcms().searchManga(source: source, query: query);
|
||||
}
|
||||
|
||||
|
||||
/***********/
|
||||
/*mangahere*/
|
||||
/***********/
|
||||
|
|
@ -64,5 +65,13 @@ Future<GetMangaModel> searchManga(SearchMangaRef ref,
|
|||
manga = await Japscan().searchManga(source: source, query: query);
|
||||
}
|
||||
|
||||
/***********/
|
||||
/*heancms*/
|
||||
/***********/
|
||||
|
||||
else if (getMangaTypeSource(source) == TypeSource.heancms) {
|
||||
manga = await HeanCms().searchManga(source: source, query: query);
|
||||
}
|
||||
|
||||
return manga!;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'search_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchMangaHash() => r'1694578ec0cc207b533f4709427d3f68b691b1b7';
|
||||
String _$searchMangaHash() => r'881d305e97081528fa6259bc4c2ea0a28b63e1fd';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -29,14 +29,14 @@ class _SystemHash {
|
|||
}
|
||||
}
|
||||
|
||||
typedef SearchMangaRef = AutoDisposeFutureProviderRef<GetMangaModel>;
|
||||
typedef SearchMangaRef = AutoDisposeFutureProviderRef<List<GetManga?>>;
|
||||
|
||||
/// See also [searchManga].
|
||||
@ProviderFor(searchManga)
|
||||
const searchMangaProvider = SearchMangaFamily();
|
||||
|
||||
/// See also [searchManga].
|
||||
class SearchMangaFamily extends Family<AsyncValue<GetMangaModel>> {
|
||||
class SearchMangaFamily extends Family<AsyncValue<List<GetManga?>>> {
|
||||
/// See also [searchManga].
|
||||
const SearchMangaFamily();
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ class SearchMangaFamily extends Family<AsyncValue<GetMangaModel>> {
|
|||
}
|
||||
|
||||
/// See also [searchManga].
|
||||
class SearchMangaProvider extends AutoDisposeFutureProvider<GetMangaModel> {
|
||||
class SearchMangaProvider extends AutoDisposeFutureProvider<List<GetManga?>> {
|
||||
/// See also [searchManga].
|
||||
SearchMangaProvider({
|
||||
required this.source,
|
||||
|
|
|
|||
157
lib/sources/multisrc/heancms/heancms.dart
Normal file
157
lib/sources/multisrc/heancms/heancms.dart
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
import 'dart:convert';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_res_to_dom_html.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/model/search.dart';
|
||||
import 'package:mangayomi/sources/multisrc/heancms/utils/utils.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class HeanCms extends MangaYomiServices {
|
||||
Map<String, String> _headers(String source) => {
|
||||
'Origin': getMangaBaseUrl(source),
|
||||
'Referer': getMangaAPIUrl(source),
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
@override
|
||||
Future<List<dynamic>> getMangaChapterUrl({required Chapter chapter}) async {
|
||||
final chapterId = chapter.url!.split("#").last;
|
||||
var request = http.Request(
|
||||
'GET',
|
||||
Uri.parse(
|
||||
'${getMangaAPIUrl("${chapter.manga.value!.source}")}series/chapter/$chapterId'));
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
});
|
||||
http.StreamedResponse response = await request.send();
|
||||
final res = await response.stream.bytesToString();
|
||||
var page = jsonDecode(res) as Map<String, dynamic>;
|
||||
for (var url in page["content"]["images"]) {
|
||||
if (url.startsWith("http")) {
|
||||
pageUrls.add(url);
|
||||
} else {
|
||||
pageUrls.add("${getMangaAPIUrl("${chapter.manga.value!.source}")}$url");
|
||||
}
|
||||
}
|
||||
return pageUrls;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
String currentSlug = manga.url!.split('/').last;
|
||||
|
||||
var request = http.Request(
|
||||
'GET',
|
||||
Uri.parse(
|
||||
'${getMangaAPIUrl(source)}series/$currentSlug#${manga.status}'));
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
});
|
||||
http.StreamedResponse response = await request.send();
|
||||
final res = await response.stream.bytesToString();
|
||||
var mangaDetail = jsonDecode(res) as Map<String, dynamic>;
|
||||
final d = Data.fromJson(mangaDetail);
|
||||
|
||||
final dom = await httpResToDom(
|
||||
url: '${getMangaBaseUrl(source)}/series/$currentSlug', headers: {});
|
||||
final des = dom
|
||||
.querySelectorAll("div.description-container")
|
||||
.map((e) => e.text.trim())
|
||||
.toList();
|
||||
final genres = dom
|
||||
.querySelectorAll("div.tags-container.pt-3 > span")
|
||||
.map((e) => e.text)
|
||||
.toList();
|
||||
final auth = dom
|
||||
.querySelectorAll("div > p")
|
||||
.where((element) => element.outerHtml.toLowerCase().contains('autor'))
|
||||
.map((e) => e.text)
|
||||
.toList();
|
||||
author = auth.first.split(":").last;
|
||||
status = manga.status;
|
||||
genre = genres;
|
||||
description = des.first;
|
||||
for (var chapter in d.chapters!) {
|
||||
chapterUrl
|
||||
.add("/series/$currentSlug/${chapter.chapterSlug}#${chapter.id}");
|
||||
chapterTitle.add(chapter.chapterName!.trim());
|
||||
chapterDate.add(parseDate(chapter.createdAt!, source));
|
||||
}
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<GetManga>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
var request = http.Request(
|
||||
'POST', Uri.parse('${getMangaAPIUrl(source)}series/querysearch'));
|
||||
request.body = json.encode({
|
||||
"page": page,
|
||||
"order": "desc",
|
||||
"order_by": "total_views",
|
||||
"series_status": "Ongoing",
|
||||
"series_type": "Comic"
|
||||
});
|
||||
request.headers.addAll(_headers(source));
|
||||
|
||||
http.StreamedResponse response = await request.send();
|
||||
final res = await response.stream.bytesToString();
|
||||
List<Data>? data;
|
||||
if (res.startsWith("{")) {
|
||||
var popularManga = jsonDecode(res) as Map<String, dynamic>;
|
||||
var popularMangaList = HeanCmsSearchModel.fromJson(popularManga);
|
||||
data = popularMangaList.data!;
|
||||
} else {
|
||||
var popularManga = jsonDecode(res) as List;
|
||||
data = popularManga.map((e) => Data.fromJson(e)).toList();
|
||||
}
|
||||
|
||||
for (var a in data) {
|
||||
statusList.add(a.status ?? "Unknown");
|
||||
image.add(a.thumbnail!.startsWith("https://")
|
||||
? a.thumbnail
|
||||
: "${getMangaAPIUrl(source)}cover/${a.thumbnail}");
|
||||
name.add(a.title);
|
||||
url.add("/series/${a.seriesSlug!.replaceAll(timeStampRegex, '')}");
|
||||
}
|
||||
|
||||
return mangaRes();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
var request = http.Request(
|
||||
'POST', Uri.parse('${getMangaAPIUrl(source)}series/search'));
|
||||
request.body = json.encode({"term": query.trim()});
|
||||
request.headers.addAll({
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
http.StreamedResponse response = await request.send();
|
||||
final res = await response.stream.bytesToString();
|
||||
List<Data>? data;
|
||||
if (res.startsWith("{")) {
|
||||
var popularManga = jsonDecode(res) as Map<String, dynamic>;
|
||||
var popularMangaList = HeanCmsSearchModel.fromJson(popularManga);
|
||||
data = popularMangaList.data!;
|
||||
} else {
|
||||
var popularManga = jsonDecode(res) as List;
|
||||
data = popularManga.map((e) => Data.fromJson(e)).toList();
|
||||
}
|
||||
|
||||
for (var a in data) {
|
||||
statusList.add(a.status ?? "Unknown");
|
||||
image.add(a.thumbnail!.startsWith("https://")
|
||||
? a.thumbnail
|
||||
: "${getMangaAPIUrl(source)}cover/${a.thumbnail}");
|
||||
name.add(a.title);
|
||||
url.add("/series/${a.seriesSlug!.replaceAll(timeStampRegex, '')}");
|
||||
}
|
||||
return mangaRes();
|
||||
}
|
||||
}
|
||||
15
lib/sources/multisrc/heancms/heancms_source_list.dart
Normal file
15
lib/sources/multisrc/heancms/heancms_source_list.dart
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
List<SourceModel> get heanCmsSourcesList => _heanCmsSourcesList;
|
||||
List<SourceModel> _heanCmsSourcesList = [
|
||||
SourceModel(
|
||||
sourceName: "Yugenmangas",
|
||||
baseUrl: "https://yugenmangas.com",
|
||||
apiUrl: "https://api.yugenmangas.com/",
|
||||
lang: "es",
|
||||
typeSource: TypeSource.heancms,
|
||||
isNsfw: true,
|
||||
logoUrl: '',
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ",
|
||||
dateFormatLocale: "en"),
|
||||
];
|
||||
136
lib/sources/multisrc/heancms/model/search.dart
Normal file
136
lib/sources/multisrc/heancms/model/search.dart
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
class HeanCmsSearchModel {
|
||||
Meta? meta;
|
||||
List<Data>? data;
|
||||
|
||||
HeanCmsSearchModel({this.meta, this.data});
|
||||
|
||||
HeanCmsSearchModel.fromJson(Map<String, dynamic> json) {
|
||||
meta = json['meta'] != null ? Meta.fromJson(json['meta']) : null;
|
||||
if (json['data'] != null) {
|
||||
data = <Data>[];
|
||||
json['data'].forEach((v) {
|
||||
data!.add(Data.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Meta {
|
||||
int? total;
|
||||
int? perPage;
|
||||
int? currentPage;
|
||||
int? lastPage;
|
||||
int? firstPage;
|
||||
String? firstPageUrl;
|
||||
String? lastPageUrl;
|
||||
String? nextPageUrl;
|
||||
|
||||
Meta({
|
||||
this.total,
|
||||
this.perPage,
|
||||
this.currentPage,
|
||||
this.lastPage,
|
||||
this.firstPage,
|
||||
this.firstPageUrl,
|
||||
this.lastPageUrl,
|
||||
this.nextPageUrl,
|
||||
});
|
||||
|
||||
Meta.fromJson(Map<String, dynamic> json) {
|
||||
total = json['total'];
|
||||
perPage = json['per_page'];
|
||||
currentPage = json['current_page'];
|
||||
lastPage = json['last_page'];
|
||||
firstPage = json['first_page'];
|
||||
firstPageUrl = json['first_page_url'];
|
||||
lastPageUrl = json['last_page_url'];
|
||||
nextPageUrl = json['next_page_url'];
|
||||
}
|
||||
}
|
||||
|
||||
class Data {
|
||||
String? title;
|
||||
int? id;
|
||||
String? seriesType;
|
||||
String? visibility;
|
||||
String? thumbnail;
|
||||
String? seriesSlug;
|
||||
String? status;
|
||||
String? latest;
|
||||
String? badge;
|
||||
List<Chapters>? chapters;
|
||||
Meta? meta;
|
||||
|
||||
Data(
|
||||
{this.title,
|
||||
this.id,
|
||||
this.seriesType,
|
||||
this.visibility,
|
||||
this.thumbnail,
|
||||
this.seriesSlug,
|
||||
this.status,
|
||||
this.latest,
|
||||
this.badge,
|
||||
this.chapters,
|
||||
this.meta});
|
||||
|
||||
Data.fromJson(Map<String, dynamic> json) {
|
||||
title = json['title'];
|
||||
id = json['id'];
|
||||
seriesType = json['series_type'];
|
||||
visibility = json['visibility'];
|
||||
thumbnail = json['thumbnail'];
|
||||
seriesSlug = json['series_slug'];
|
||||
status = json['status'];
|
||||
latest = json['latest'];
|
||||
badge = json['badge'];
|
||||
if (json['chapters'] != null) {
|
||||
chapters = <Chapters>[];
|
||||
json['chapters'].forEach((v) {
|
||||
chapters!.add(Chapters.fromJson(v));
|
||||
});
|
||||
}
|
||||
meta = json['meta'] != null ? Meta.fromJson(json['meta']) : null;
|
||||
}
|
||||
}
|
||||
|
||||
class Chapters {
|
||||
int? id;
|
||||
String? index;
|
||||
String? chapterName;
|
||||
String? chapterSlug;
|
||||
String? createdAt;
|
||||
String? updatedAt;
|
||||
int? seriesId;
|
||||
|
||||
Chapters(
|
||||
{this.id,
|
||||
this.index,
|
||||
this.chapterName,
|
||||
this.chapterSlug,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
this.seriesId});
|
||||
|
||||
Chapters.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
index = json['index'];
|
||||
chapterName = json['chapter_name'];
|
||||
chapterSlug = json['chapter_slug'];
|
||||
createdAt = json['created_at'];
|
||||
updatedAt = json['updated_at'];
|
||||
seriesId = json['series_id'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
data['id'] = id;
|
||||
data['index'] = index;
|
||||
data['chapter_name'] = chapterName;
|
||||
data['chapter_slug'] = chapterSlug;
|
||||
data['created_at'] = createdAt;
|
||||
data['updated_at'] = updatedAt;
|
||||
data['series_id'] = seriesId;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
2
lib/sources/multisrc/heancms/utils/utils.dart
Normal file
2
lib/sources/multisrc/heancms/utils/utils.dart
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
RegExp timeStampRegex = RegExp("-\\d+");
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
List<SourceModel> mangathemesiaSourcesList = [
|
||||
List<SourceModel> get mangathemesiaSourcesList => _mangathemesiaSourcesList;
|
||||
List<SourceModel> _mangathemesiaSourcesList = [
|
||||
SourceModel(
|
||||
sourceName: "KomikLab",
|
||||
url: "https://komiklab.com",
|
||||
baseUrl: "https://komiklab.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -11,7 +12,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "AnimatedGlitchedScans",
|
||||
url: "https://anigliscans.com",
|
||||
baseUrl: "https://anigliscans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -19,7 +20,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "ArenaScans",
|
||||
// url: "https://arenascans.net",
|
||||
// baseUrl: "https://arenascans.net",
|
||||
// lang: "en",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl:
|
||||
|
|
@ -27,14 +28,14 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// isCloudflare: true),
|
||||
// SourceModel(
|
||||
// sourceName: "AzureScans",
|
||||
// url: "https://azuremanga.com",
|
||||
// baseUrl: "https://azuremanga.com",
|
||||
// lang: "en",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: ''),
|
||||
|
||||
SourceModel(
|
||||
sourceName: "Boosei",
|
||||
url: "https://boosei.net",
|
||||
baseUrl: "https://boosei.net",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -43,7 +44,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "id"),
|
||||
SourceModel(
|
||||
sourceName: "Clayrer",
|
||||
url: "https://clayrer.net",
|
||||
baseUrl: "https://clayrer.net",
|
||||
lang: "es",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -52,7 +53,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "es"),
|
||||
SourceModel(
|
||||
sourceName: "CosmicScans",
|
||||
url: "https://cosmicscans.com",
|
||||
baseUrl: "https://cosmicscans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -60,7 +61,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "DiskusScan",
|
||||
url: "https://diskusscan.com",
|
||||
baseUrl: "https://diskusscan.com",
|
||||
lang: "pt-br",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -69,7 +70,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "pt"),
|
||||
SourceModel(
|
||||
sourceName: "DuniaKomik",
|
||||
url: "https://duniakomik.id",
|
||||
baseUrl: "https://duniakomik.id",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -77,19 +78,19 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "id"),
|
||||
// SourceModel(
|
||||
// sourceName: "FlameScans",
|
||||
// url: "https://flamescans.fr",
|
||||
// baseUrl: "https://flamescans.fr",
|
||||
// lang: "fr",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: ''),
|
||||
// SourceModel(
|
||||
// sourceName: "GremoryMangas",
|
||||
// url: "https://gremorymangas.com",
|
||||
// baseUrl: "https://gremorymangas.com",
|
||||
// lang: "es",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: 'https://gremorymangas.com/wp-content/uploads/2022/09/6941.png'),
|
||||
SourceModel(
|
||||
sourceName: "InfernalVoidScans",
|
||||
url: "https://void-scans.com",
|
||||
baseUrl: "https://void-scans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -99,7 +100,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
|
||||
// SourceModel(
|
||||
// sourceName: "Kiryuu",
|
||||
// url: "https://kiryuu.id",
|
||||
// baseUrl: "https://kiryuu.id",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -107,7 +108,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "id"),
|
||||
// SourceModel(
|
||||
// sourceName: "KomikIndo",
|
||||
// url: "https://komikindo.co",
|
||||
// baseUrl: "https://komikindo.co",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -115,7 +116,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "id"),
|
||||
SourceModel(
|
||||
sourceName: "KomikMama",
|
||||
url: "https://komikmama.co",
|
||||
baseUrl: "https://komikmama.co",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
|
|
@ -123,7 +124,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "id"),
|
||||
SourceModel(
|
||||
sourceName: "Komiku",
|
||||
url: "https://komiku.com",
|
||||
baseUrl: "https://komiku.com",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: 'https://komiku.com/wp-content/uploads/2022/03/logooo.png',
|
||||
|
|
@ -131,7 +132,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "id"),
|
||||
SourceModel(
|
||||
sourceName: "KumaScans (Kuma Translation)",
|
||||
url: "https://kumascans.com",
|
||||
baseUrl: "https://kumascans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -140,7 +141,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "MangaKita",
|
||||
// url: "https://mangakita.net",
|
||||
// baseUrl: "https://mangakita.net",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -148,7 +149,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "MangaTale",
|
||||
// url: "https://mangatale.co",
|
||||
// baseUrl: "https://mangatale.co",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl:
|
||||
|
|
@ -157,7 +158,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "MangaYaro",
|
||||
url: "https://mangayaro.net",
|
||||
baseUrl: "https://mangayaro.net",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -166,7 +167,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "MangKomik",
|
||||
url: "https://mangkomik.net",
|
||||
baseUrl: "https://mangkomik.net",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -175,7 +176,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "id"),
|
||||
SourceModel(
|
||||
sourceName: "MangásChan",
|
||||
url: "https://mangaschan.com",
|
||||
baseUrl: "https://mangaschan.com",
|
||||
lang: "pt-br",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: 'https://mangaschan.com/wp-content/uploads/Logo-web.webp',
|
||||
|
|
@ -183,7 +184,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "pt-br"),
|
||||
// SourceModel(
|
||||
// sourceName: "ManhwaFreak",
|
||||
// url: "https://manhwafreak.com",
|
||||
// baseUrl: "https://manhwafreak.com",
|
||||
// lang: "en",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl:
|
||||
|
|
@ -192,7 +193,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "ManhwaList",
|
||||
url: "https://manhwalist.in",
|
||||
baseUrl: "https://manhwalist.in",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: 'https://manhwalist.in/wp-content/uploads/2022/12/4666667.png',
|
||||
|
|
@ -200,7 +201,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "MasterKomik",
|
||||
// url: "https://masterkomik.com",
|
||||
// baseUrl: "https://masterkomik.com",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: 'https://masterkomik.com/wp-content/uploads/2020/12/New-MK.png',
|
||||
|
|
@ -208,7 +209,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "id"),
|
||||
// SourceModel(
|
||||
// sourceName: "Nekomik",
|
||||
// url: "https://nekomik.com",
|
||||
// baseUrl: "https://nekomik.com",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -216,7 +217,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "PhantomScans",
|
||||
// url: "https://phantomscans.com",
|
||||
// baseUrl: "https://phantomscans.com",
|
||||
// lang: "en",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -224,7 +225,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "PhoenixFansub",
|
||||
// url: "https://phoenixfansub.com",
|
||||
// baseUrl: "https://phoenixfansub.com",
|
||||
// lang: "es",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: '',
|
||||
|
|
@ -232,7 +233,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "es"),
|
||||
SourceModel(
|
||||
sourceName: "PiScans",
|
||||
url: "https://piscans.in",
|
||||
baseUrl: "https://piscans.in",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -241,7 +242,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "Rawkuma",
|
||||
// url: "https://rawkuma.com/",
|
||||
// baseUrl: "https://rawkuma.com/",
|
||||
// lang: "ja",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: 'http://rawkuma.com/wp-content/uploads/2021/12/Rawkuma-Logo.png',
|
||||
|
|
@ -249,7 +250,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "Readkomik",
|
||||
url: "https://readkomik.com",
|
||||
baseUrl: "https://readkomik.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -258,7 +259,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "SuryaScans",
|
||||
url: "https://suryascans.com",
|
||||
baseUrl: "https://suryascans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -267,7 +268,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "SushiScan",
|
||||
url: "https://sushiscan.net",
|
||||
baseUrl: "https://sushiscan.net",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: 'https://sushiscan.net/wp-content/uploads/SushiScanNewLogo.png',
|
||||
|
|
@ -276,7 +277,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "fr"),
|
||||
SourceModel(
|
||||
sourceName: "TsundokuTraduções",
|
||||
url: "https://tsundoku.com.br",
|
||||
baseUrl: "https://tsundoku.com.br",
|
||||
lang: "pt-br",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -285,7 +286,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "pt-br"),
|
||||
SourceModel(
|
||||
sourceName: "TukangKomik",
|
||||
url: "https://tukangkomik.id",
|
||||
baseUrl: "https://tukangkomik.id",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -294,7 +295,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
// SourceModel(
|
||||
// sourceName: "WestManga",
|
||||
// url: "https://westmanga.info",
|
||||
// baseUrl: "https://westmanga.info",
|
||||
// lang: "id",
|
||||
// typeSource: TypeSource.mangathemesia,
|
||||
// logoUrl: 'https://westmanga.info/wp-content/uploads/2021/01/LOGOxx-1.png',
|
||||
|
|
@ -302,7 +303,7 @@ List<SourceModel> mangathemesiaSourcesList = [
|
|||
// dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "xCaliBRScans",
|
||||
url: "https://xcalibrscans.com",
|
||||
baseUrl: "https://xcalibrscans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl:
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
import 'package:html/dom.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class MangaThemeSia extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final dom = await httpGet(
|
||||
url: url,
|
||||
url: manga.url!,
|
||||
source: source,
|
||||
resDom: true,
|
||||
useUserAgent: true) as Document?;
|
||||
|
|
@ -138,17 +136,17 @@ class MangaThemeSia extends MangaYomiServices {
|
|||
}
|
||||
}
|
||||
}
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
source = source.toLowerCase();
|
||||
final dom = await httpGet(
|
||||
useUserAgent: true,
|
||||
url: '${getWpMangaUrl(source)}/manga/?title=&page=$page&order=popular',
|
||||
url:
|
||||
'${getMangaBaseUrl(source)}/manga/?title=&page=$page&order=popular',
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
if (dom!
|
||||
|
|
@ -189,10 +187,10 @@ class MangaThemeSia extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final dom = await httpGet(
|
||||
url: '${getWpMangaUrl(source)}/?s=${query.trim()}',
|
||||
url: '${getMangaBaseUrl(source)}/?s=${query.trim()}',
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
if (dom!
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
List<SourceModel> mmrcmsSourcesList = [
|
||||
|
||||
|
||||
List<SourceModel> get mmrcmsSourcesList => _mmrcmsSourcesList;
|
||||
List<SourceModel> _mmrcmsSourcesList = [
|
||||
// SourceModel(
|
||||
// sourceName: "Fallen Angels",
|
||||
// url: "https://manga.fascans.com",
|
||||
// baseUrl: "https://manga.fascans.com",
|
||||
// lang: "en",
|
||||
// typeSource: TypeSource.mmrcms,
|
||||
// logoUrl: '',
|
||||
|
|
@ -13,7 +12,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
// dateFormatLocale: "en_US"),
|
||||
SourceModel(
|
||||
sourceName: "Scan FR",
|
||||
url: "https://www.scan-fr.org",
|
||||
baseUrl: "https://www.scan-fr.org",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.mmrcms,
|
||||
logoUrl: '',
|
||||
|
|
@ -21,7 +20,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
dateFormatLocale: "en_US"),
|
||||
SourceModel(
|
||||
sourceName: "Scan VF",
|
||||
url: "https://www.scan-vf.net",
|
||||
baseUrl: "https://www.scan-vf.net",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.mmrcms,
|
||||
logoUrl: '',
|
||||
|
|
@ -29,7 +28,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
dateFormatLocale: "en_US"), //
|
||||
SourceModel(
|
||||
sourceName: "Komikid",
|
||||
url: "https://www.komikid.com",
|
||||
baseUrl: "https://www.komikid.com",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mmrcms,
|
||||
logoUrl: '',
|
||||
|
|
@ -37,7 +36,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
dateFormatLocale: "en_US"),
|
||||
// SourceModel(
|
||||
// sourceName: "MangaHanta",
|
||||
// url: "http://mangahanta.com",
|
||||
// baseUrl: "http://mangahanta.com",
|
||||
// lang: "tr",
|
||||
// typeSource: TypeSource.mmrcms,
|
||||
// logoUrl: '',
|
||||
|
|
@ -45,7 +44,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
// dateFormatLocale: "en_US"),
|
||||
SourceModel(
|
||||
sourceName: "MangaID",
|
||||
url: "https://mangaid.click",
|
||||
baseUrl: "https://mangaid.click",
|
||||
lang: "id",
|
||||
typeSource: TypeSource.mmrcms,
|
||||
logoUrl: '',
|
||||
|
|
@ -53,7 +52,7 @@ List<SourceModel> mmrcmsSourcesList = [
|
|||
dateFormatLocale: "en_US"),
|
||||
SourceModel(
|
||||
sourceName: "Jpmangas",
|
||||
url: "https://jpmangas.cc",
|
||||
baseUrl: "https://jpmangas.cc",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.mmrcms,
|
||||
logoUrl: '',
|
||||
|
|
@ -3,20 +3,18 @@ import 'dart:convert';
|
|||
import 'package:html/dom.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
|
||||
class Mmrcms extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final dom =
|
||||
await httpGet(url: url, source: source, resDom: true) as Document?;
|
||||
final dom = await httpGet(url: manga.url!, source: source, resDom: true)
|
||||
as Document?;
|
||||
description = dom!
|
||||
.querySelectorAll('.row .well p')
|
||||
.map((e) => e.text.trim())
|
||||
|
|
@ -73,9 +71,9 @@ class Mmrcms extends MangaYomiServices {
|
|||
final data = rrr.map((e) => e.outerHtml).toList();
|
||||
if (source.toLowerCase() == 'jpmangas' ||
|
||||
source.toLowerCase() == 'fr scan') {
|
||||
imageUrl = regSrcMatcher(data.first).replaceAll('//', 'https://');
|
||||
manga.imageUrl = regSrcMatcher(data.first).replaceAll('//', 'https://');
|
||||
} else {
|
||||
imageUrl = regSrcMatcher(data.first);
|
||||
manga.imageUrl = regSrcMatcher(data.first);
|
||||
}
|
||||
|
||||
final ttt = dom
|
||||
|
|
@ -101,16 +99,15 @@ class Mmrcms extends MangaYomiServices {
|
|||
chapterDate.add(parseDate(da, source));
|
||||
}
|
||||
}
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
final dom = await httpGet(
|
||||
url:
|
||||
'${getWpMangaUrl(source)}/filterList?page=$page&sortBy=views&asc=false',
|
||||
'${getMangaBaseUrl(source)}/filterList?page=$page&sortBy=views&asc=false',
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
final urlElement = dom!.getElementsByClassName('chart-title');
|
||||
|
|
@ -132,20 +129,20 @@ class Mmrcms extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final response = await httpGet(
|
||||
url: '${getWpMangaUrl(source)}/search?query=${query.trim()}',
|
||||
url: '${getMangaBaseUrl(source)}/search?query=${query.trim()}',
|
||||
source: source,
|
||||
resDom: false) as String?;
|
||||
final rep = jsonDecode(response!);
|
||||
for (var ok in rep['suggestions']) {
|
||||
if (source == 'Read Comics Online') {
|
||||
url.add('${getWpMangaUrl(source)}/comic/${ok['data']}');
|
||||
url.add('${getMangaBaseUrl(source)}/comic/${ok['data']}');
|
||||
} else if (source == 'Scan VF') {
|
||||
url.add('${getWpMangaUrl(source)}/${ok['data']}');
|
||||
url.add('${getMangaBaseUrl(source)}/${ok['data']}');
|
||||
} else {
|
||||
url.add('${getWpMangaUrl(source)}/manga/${ok['data']}');
|
||||
url.add('${getMangaBaseUrl(source)}/manga/${ok['data']}');
|
||||
}
|
||||
name.add(ok["value"]);
|
||||
image.add('');
|
||||
|
|
@ -163,7 +160,8 @@ class Mmrcms extends MangaYomiServices {
|
|||
if (dom!.querySelectorAll('#all > .img-responsive').isNotEmpty) {
|
||||
pageUrls = dom.querySelectorAll('#all > .img-responsive').map((e) {
|
||||
final RegExp regexx = RegExp(r'data-src="([^"]+)"');
|
||||
if (chapter.manga.value!.source!.toLowerCase() == 'fr scan') {
|
||||
if (chapter.manga.value!.source!.toLowerCase() == 'fr scan' ||
|
||||
chapter.manga.value!.source!.toLowerCase() == 'jpmangas') {
|
||||
return regexx
|
||||
.allMatches(e.outerHtml)
|
||||
.first
|
||||
|
|
@ -5,29 +5,34 @@ abstract class MangaYomiServices {
|
|||
List<String?> name = [];
|
||||
List<String?> image = [];
|
||||
List<String> genre = [];
|
||||
String? author;
|
||||
String? status;
|
||||
String? author = "";
|
||||
String? status = "";
|
||||
List<String> statusList = [];
|
||||
List<String> chapterTitle = [];
|
||||
List<String> chapterUrl = [];
|
||||
List<String> chapterDate = [];
|
||||
String? description;
|
||||
String? description = "";
|
||||
List<Chapter> chapters = [];
|
||||
List<String> scanlators = [];
|
||||
List pageUrls = [];
|
||||
|
||||
GetMangaModel mangaRes() {
|
||||
return GetMangaModel(
|
||||
name: name,
|
||||
url: url,
|
||||
image: image,
|
||||
);
|
||||
List<GetManga> mangaList = [];
|
||||
List<GetManga> mangaRes() {
|
||||
for (var i = 0; i < name.length; i++) {
|
||||
mangaList.add(GetManga(
|
||||
genre: genre,
|
||||
author: author,
|
||||
status: statusList.isEmpty ? "" : statusList[i],
|
||||
chapters: chapters,
|
||||
imageUrl: image[i],
|
||||
description: description,
|
||||
url: url[i],
|
||||
name: name[i],
|
||||
source: ""));
|
||||
}
|
||||
return mangaList;
|
||||
}
|
||||
|
||||
GetMangaDetailModel mangadetailRes(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
required String source}) {
|
||||
GetManga mangadetailRes({required GetManga manga, required String source}) {
|
||||
if (chapterDate.isNotEmpty &&
|
||||
chapterTitle.isNotEmpty &&
|
||||
chapterUrl.isNotEmpty) {
|
||||
|
|
@ -43,48 +48,31 @@ abstract class MangaYomiServices {
|
|||
mangaId: null));
|
||||
}
|
||||
}
|
||||
return GetMangaDetailModel(
|
||||
return GetManga(
|
||||
status: status,
|
||||
genre: genre,
|
||||
author: author,
|
||||
description: description,
|
||||
name: title,
|
||||
url: url,
|
||||
name: manga.name,
|
||||
url: manga.url,
|
||||
source: source,
|
||||
imageUrl: imageUrl,
|
||||
imageUrl: manga.imageUrl,
|
||||
chapters: chapters,
|
||||
);
|
||||
}
|
||||
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page});
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
required String lang,
|
||||
required String source});
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga, required String lang, required String source});
|
||||
Future<List<dynamic>?> getMangaChapterUrl({
|
||||
required Chapter chapter,
|
||||
});
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query});
|
||||
}
|
||||
|
||||
|
||||
|
||||
class GetMangaModel {
|
||||
late List<String?> url;
|
||||
late List<String?> name;
|
||||
late List<String?> image;
|
||||
GetMangaModel({
|
||||
required this.name,
|
||||
required this.url,
|
||||
required this.image,
|
||||
});
|
||||
}
|
||||
|
||||
class GetMangaDetailModel {
|
||||
class GetManga {
|
||||
List<String> genre = [];
|
||||
List<Chapter> chapters = [];
|
||||
String? author;
|
||||
|
|
@ -94,7 +82,7 @@ class GetMangaDetailModel {
|
|||
String? name;
|
||||
String? imageUrl;
|
||||
String? description;
|
||||
GetMangaDetailModel({
|
||||
GetManga({
|
||||
required this.genre,
|
||||
required this.author,
|
||||
required this.status,
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import 'package:mangayomi/models/source_model.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/en/mangahere/mangahere_source.dart';
|
||||
import 'package:mangayomi/sources/src/fr/japscan/japscan_source.dart';
|
||||
import 'package:mangayomi/sources/src/fr/mangakawaii/mangakawaii_source.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mangathemesia/mangathemesia_source_list.dart';
|
||||
import 'package:mangayomi/sources/src/multi/mmrcms/mmrcms_source_list.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mangathemesia/mangathemesia_source_list.dart';
|
||||
import 'package:mangayomi/sources/multisrc/mmrcms/mmrcms_source_list.dart';
|
||||
|
||||
List<SourceModel> get sourcesList => _sourcesList;
|
||||
List<SourceModel> _sourcesList = [
|
||||
|
|
@ -13,5 +14,6 @@ List<SourceModel> _sourcesList = [
|
|||
...mangathemesiaSourcesList,
|
||||
...comickSourcesList,
|
||||
...mmrcmsSourcesList,
|
||||
japscanSource
|
||||
japscanSource,
|
||||
...heanCmsSourcesList
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
String logoUrl =
|
||||
const logoUrl =
|
||||
'https://comick.app/_next/image?url=%2Fstatic%2Ficons%2Funicorn-64.png&w=144&q=75';
|
||||
String apiUrl = 'https://api.comick.fun/';
|
||||
List<SourceModel> comickSourcesList = [
|
||||
const apiUrl = 'https://api.comick.fun/';
|
||||
const baseUrl = 'https://comick.app/';
|
||||
|
||||
List<SourceModel> get comickSourcesList => _comickSourcesList;
|
||||
List<SourceModel> _comickSourcesList = [
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'en',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -14,7 +18,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ar',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -22,7 +27,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pt',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -30,7 +36,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pt-br',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -38,7 +45,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'it',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -46,7 +54,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ru',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -54,7 +63,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'es',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -62,7 +72,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'es-419',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -70,7 +81,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'id',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -78,7 +90,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'hi',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -86,7 +99,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'de',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -94,7 +108,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'ja',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -102,7 +117,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'tr',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -110,7 +126,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'pl',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -118,7 +135,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'zh',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -126,7 +144,8 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'zh-hk',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
|
|
@ -134,26 +153,11 @@ List<SourceModel> comickSourcesList = [
|
|||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: 'Comick',
|
||||
url: apiUrl,
|
||||
apiUrl: apiUrl,
|
||||
baseUrl: baseUrl,
|
||||
lang: 'fr',
|
||||
typeSource: TypeSource.comick,
|
||||
logoUrl: logoUrl,
|
||||
dateFormat: "yyyy-MM-dd'T'HH:mm:ss'Z'",
|
||||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "KomikLab",
|
||||
url: "https://komiklab.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en"),
|
||||
SourceModel(
|
||||
sourceName: "AnimatedGlitchedScans",
|
||||
url: "https://anigliscans.com",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.mangathemesia,
|
||||
logoUrl: '',
|
||||
dateFormat: "MMMM dd, yyyy",
|
||||
dateFormatLocale: "en"),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/comick/chapter_page_comick.dart';
|
||||
import 'package:mangayomi/models/comick/manga_chapter_detail.dart';
|
||||
import 'package:mangayomi/models/comick/manga_detail_comick.dart';
|
||||
import 'package:mangayomi/models/comick/popular_manga_comick.dart';
|
||||
import 'package:mangayomi/models/comick/search_manga_cimick.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/model/chapter_page_comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/model/manga_chapter_detail.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/model/manga_detail_comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/model/popular_manga_comick.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/model/search_manga_cimick.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/utils/utils.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class Comick extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
source = source.toLowerCase();
|
||||
final response = await httpGet(
|
||||
|
|
@ -34,14 +34,12 @@ class Comick extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final response = await httpGet(
|
||||
url: 'https://api.comick.fun$url?tachiyomi=true',
|
||||
url: 'https://api.comick.fun${manga.url}?tachiyomi=true',
|
||||
source: source,
|
||||
resDom: false) as String?;
|
||||
var mangaDetail = jsonDecode(response!) as Map<String, dynamic>;
|
||||
|
|
@ -86,12 +84,11 @@ class Comick extends MangaYomiServices {
|
|||
chapter.vol ?? "", chapter.chap ?? "", chapter.title ?? "", lang));
|
||||
}
|
||||
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final response = await httpGet(
|
||||
url:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
SourceModel mangahereSource = SourceModel(
|
||||
SourceModel get mangahereSource => _mangahereSource;
|
||||
|
||||
SourceModel _mangahereSource = SourceModel(
|
||||
sourceName: "MangaHere",
|
||||
url: "http://www.mangahere.cc",
|
||||
baseUrl: "http://www.mangahere.cc",
|
||||
lang: "en",
|
||||
typeSource: TypeSource.single,
|
||||
logoUrl: 'http://static.mangahere.cc/v20210106/mangahere/images/logo.png',
|
||||
|
|
|
|||
|
|
@ -2,21 +2,19 @@ import 'package:flutter_js/flutter_js.dart';
|
|||
import 'package:html/dom.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:html/dom.dart' as dom;
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class Mangahere extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final dom = await httpGet(
|
||||
url: "http://www.mangahere.cc$url",
|
||||
url: "http://www.mangahere.cc${manga.url}",
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
if (dom!
|
||||
|
|
@ -104,12 +102,11 @@ class Mangahere extends MangaYomiServices {
|
|||
genre.add(ok);
|
||||
}
|
||||
}
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
final dom = await httpGet(
|
||||
url: 'https://www.mangahere.cc/ranking/',
|
||||
|
|
@ -145,11 +142,11 @@ class Mangahere extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final dom = await httpGet(
|
||||
url:
|
||||
'${getWpMangaUrl(source)}/search?title=${query.trim()}&genres=&nogenres=&sort=&stype=1&name=&type=0&author_method=cw&author=&artist_method=cw&artist=&rating_method=eq&rating=&released_method=eq&released=&st=0',
|
||||
'${getMangaBaseUrl(source)}/search?title=${query.trim()}&genres=&nogenres=&sort=&stype=1&name=&type=0&author_method=cw&author=&artist_method=cw&artist=&rating_method=eq&rating=&released_method=eq&released=&st=0',
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
SourceModel japscanSource = SourceModel(
|
||||
SourceModel get japscanSource => _japscanSource;
|
||||
|
||||
SourceModel _japscanSource = SourceModel(
|
||||
sourceName: "Japscan",
|
||||
url: "https://japscan.lol",
|
||||
baseUrl: "https://japscan.lol",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.single,
|
||||
logoUrl: '',
|
||||
|
|
|
|||
|
|
@ -7,27 +7,25 @@ import 'package:html/dom.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/cloudflare/cloudflare_bypass.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class Japscan extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final dom =
|
||||
await httpGet(url: url, source: source, resDom: true) as Document?;
|
||||
final dom = await httpGet(url: manga.url!, source: source, resDom: true)
|
||||
as Document?;
|
||||
if (dom!.querySelectorAll('.col-7 > p').isNotEmpty) {
|
||||
final images =
|
||||
dom.querySelectorAll('.col-5 ').map((e) => e.outerHtml).toList();
|
||||
RegExp exp = RegExp(r'src="([^"]+)"');
|
||||
|
||||
String? srcValue = exp.firstMatch(images[0])?.group(1);
|
||||
imageUrl = 'https://www.japscan.lol$srcValue';
|
||||
manga.imageUrl = 'https://www.japscan.lol$srcValue';
|
||||
|
||||
if (dom.querySelectorAll('.col-7 > p').isNotEmpty) {
|
||||
final stat = dom
|
||||
|
|
@ -98,12 +96,11 @@ class Japscan extends MangaYomiServices {
|
|||
chapterDate.add(parseDate(ok, source));
|
||||
}
|
||||
}
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
final dom = await httpGet(
|
||||
url: "https://www.japscan.lol/",
|
||||
|
|
@ -131,7 +128,7 @@ class Japscan extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final dom = await httpGet(
|
||||
url: "https://www.google.com/search?q=${query.toLowerCase()}+japscan",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
|
||||
SourceModel mangakawaiiSource = SourceModel(
|
||||
SourceModel get mangakawaiiSource => _mangakawaiiSource;
|
||||
SourceModel _mangakawaiiSource = SourceModel(
|
||||
sourceName: "MangaKawaii",
|
||||
url: "https://www.mangakawaii.io",
|
||||
baseUrl: "https://www.mangakawaii.io",
|
||||
lang: "fr",
|
||||
typeSource: TypeSource.single,
|
||||
logoUrl: 'https://www.mangakawaii.io/assets/img/logo.png',
|
||||
|
|
|
|||
|
|
@ -2,16 +2,14 @@ import 'package:html/dom.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/http_service/http_res_to_dom_html.dart';
|
||||
import 'package:mangayomi/services/http_service/http_service.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/src/all/comick/src/utils/utils.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
|
||||
class MangaKawaii extends MangaYomiServices {
|
||||
@override
|
||||
Future<GetMangaDetailModel?> getMangaDetail(
|
||||
{required String imageUrl,
|
||||
required String url,
|
||||
required String title,
|
||||
Future<GetManga?> getMangaDetail(
|
||||
{required GetManga manga,
|
||||
required String lang,
|
||||
required String source}) async {
|
||||
final dom = await httpGet(
|
||||
|
|
@ -19,7 +17,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
source: source,
|
||||
resDom: true) as Document?;
|
||||
List detail = [];
|
||||
imageUrl =
|
||||
manga.imageUrl =
|
||||
"https://cdn.mangakawaii.pics/uploads$url/cover/cover_250x350.jpg";
|
||||
if (dom!.querySelectorAll('dd.text-justify.text-break').isNotEmpty) {
|
||||
final tt = dom
|
||||
|
|
@ -117,12 +115,11 @@ class MangaKawaii extends MangaYomiServices {
|
|||
}
|
||||
}
|
||||
}
|
||||
return mangadetailRes(
|
||||
imageUrl: imageUrl, url: url, title: title, source: source);
|
||||
return mangadetailRes(manga: manga, source: source);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> getPopularManga(
|
||||
Future<List<GetManga?>> getPopularManga(
|
||||
{required String source, required int page}) async {
|
||||
final dom = await httpGet(
|
||||
url: 'https://www.mangakawaii.io/',
|
||||
|
|
@ -146,7 +143,7 @@ class MangaKawaii extends MangaYomiServices {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<GetMangaModel?> searchManga(
|
||||
Future<List<GetManga?>> searchManga(
|
||||
{required String source, required String query}) async {
|
||||
final dom = await httpGet(
|
||||
url:
|
||||
|
|
|
|||
|
|
@ -2,17 +2,27 @@ import 'package:intl/intl.dart';
|
|||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/sources/source_list.dart';
|
||||
|
||||
String getWpMangaUrl(String source) {
|
||||
String getMangaBaseUrl(String source) {
|
||||
String url = "";
|
||||
for (var i = 0; i < sourcesList.length; i++) {
|
||||
if (sourcesList[i].sourceName.toLowerCase() == source.toLowerCase()) {
|
||||
url = sourcesList[i].url;
|
||||
url = sourcesList[i].baseUrl;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
TypeSource getWpMangTypeSource(String source) {
|
||||
String getMangaAPIUrl(String source) {
|
||||
String url = "";
|
||||
for (var i = 0; i < sourcesList.length; i++) {
|
||||
if (sourcesList[i].sourceName.toLowerCase() == source.toLowerCase()) {
|
||||
url = sourcesList[i].apiUrl;
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
TypeSource getMangaTypeSource(String source) {
|
||||
TypeSource? typeSource;
|
||||
for (var i = 0; i < sourcesList.length; i++) {
|
||||
if (sourcesList[i].sourceName.toLowerCase() == source.toLowerCase()) {
|
||||
|
|
@ -59,7 +69,15 @@ String utilDate(String data) {
|
|||
|
||||
parseDate(String data, String source) {
|
||||
source = source.toLowerCase();
|
||||
DateTime date = DateFormat(getFormatDate(source), getFormatDateLocale(source))
|
||||
.parse(data);
|
||||
final now = DateTime.now();
|
||||
DateTime? date;
|
||||
if (data.toLowerCase() == "yesterday") {
|
||||
date = DateTime(now.year, now.month, now.day - 1);
|
||||
} else if (data.toLowerCase().contains("hour ago")) {
|
||||
date = now;
|
||||
} else {
|
||||
date = DateFormat(getFormatDate(source), getFormatDateLocale(source))
|
||||
.parse(data);
|
||||
}
|
||||
return date.millisecondsSinceEpoch.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ class ExtensionScreen extends ConsumerWidget {
|
|||
"${element.sourceName}${element.lang}",
|
||||
SourceModel(
|
||||
sourceName: element.sourceName,
|
||||
url: element.url,
|
||||
baseUrl: element.baseUrl,
|
||||
apiUrl: element.apiUrl,
|
||||
lang: element.lang,
|
||||
typeSource: element.typeSource,
|
||||
isAdded: val,
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@ part 'refresh_filter_data.g.dart';
|
|||
|
||||
@riverpod
|
||||
refreshFilterData(RefreshFilterDataRef ref) async {
|
||||
final lf = ref
|
||||
.watch(hiveBoxMangaProvider)
|
||||
.get("language_filter", defaultValue: []);
|
||||
final lf =
|
||||
ref.watch(hiveBoxMangaProvider).get("language_filter", defaultValue: []);
|
||||
if (lf.isEmpty) {
|
||||
for (var element in sourcesList) {
|
||||
final sP = ref.watch(hiveBoxMangaSourceProvider);
|
||||
|
|
@ -20,7 +19,8 @@ refreshFilterData(RefreshFilterDataRef ref) async {
|
|||
"${element.sourceName}${element.lang}",
|
||||
SourceModel(
|
||||
sourceName: element.sourceName,
|
||||
url: element.url,
|
||||
baseUrl: element.baseUrl,
|
||||
apiUrl: element.apiUrl,
|
||||
lang: element.lang,
|
||||
typeSource: element.typeSource,
|
||||
logoUrl: element.logoUrl,
|
||||
|
|
@ -47,7 +47,8 @@ refreshFilterData(RefreshFilterDataRef ref) async {
|
|||
"${element.sourceName}${element.lang}",
|
||||
SourceModel(
|
||||
sourceName: element.sourceName,
|
||||
url: element.url,
|
||||
baseUrl: element.baseUrl,
|
||||
apiUrl: element.apiUrl,
|
||||
lang: element.lang,
|
||||
typeSource: element.typeSource,
|
||||
logoUrl: element.logoUrl,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'refresh_filter_data.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$refreshFilterDataHash() => r'60c9569f6062e6f951b735873f92a89885cc5964';
|
||||
String _$refreshFilterDataHash() => r'03aed46bb9e7b0ee3d7e99b99784d3080751895b';
|
||||
|
||||
/// See also [refreshFilterData].
|
||||
@ProviderFor(refreshFilterData)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:mangayomi/providers/hive_provider.dart';
|
|||
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||
import 'package:mangayomi/services/search_manga.dart';
|
||||
import 'package:mangayomi/models/source_model.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/lang.dart';
|
||||
|
|
@ -121,15 +122,13 @@ class SourceSearchScreen extends ConsumerWidget {
|
|||
error: (error, stackTrace) =>
|
||||
Center(child: Text(error.toString())),
|
||||
data: (data) {
|
||||
if (data.name.isNotEmpty) {
|
||||
if (data.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: data.name.length,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
return MangaGlobalImageCard(
|
||||
url: data.url[index]!,
|
||||
name: data.name[index]!,
|
||||
image: data.image[index]!,
|
||||
manga: data[index]!,
|
||||
source: source.sourceName,
|
||||
lang: source.lang,
|
||||
);
|
||||
|
|
@ -148,16 +147,12 @@ class SourceSearchScreen extends ConsumerWidget {
|
|||
}
|
||||
|
||||
class MangaGlobalImageCard extends ConsumerStatefulWidget {
|
||||
final String image;
|
||||
final String url;
|
||||
final String name;
|
||||
final GetManga manga;
|
||||
final String source;
|
||||
final String lang;
|
||||
const MangaGlobalImageCard({
|
||||
super.key,
|
||||
required this.url,
|
||||
required this.name,
|
||||
required this.image,
|
||||
required this.manga,
|
||||
required this.source,
|
||||
required this.lang,
|
||||
});
|
||||
|
|
@ -173,11 +168,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final getMangaDetail = ref.watch(getMangaDetailProvider(
|
||||
source: widget.source,
|
||||
imageUrl: widget.image,
|
||||
title: widget.name,
|
||||
url: widget.url,
|
||||
lang: widget.lang));
|
||||
source: widget.source, manga: widget.manga, lang: widget.lang));
|
||||
|
||||
return getMangaDetail.when(
|
||||
data: (data) {
|
||||
|
|
@ -237,7 +228,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
fit: BoxFit.fill),
|
||||
BottomTextWidget(
|
||||
fontSize: 12.0,
|
||||
text: widget.name,
|
||||
text: widget.manga.name!,
|
||||
isLoading: true,
|
||||
isComfortableGrid: true,
|
||||
)
|
||||
|
|
@ -258,7 +249,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
),
|
||||
BottomTextWidget(
|
||||
fontSize: 12.0,
|
||||
text: widget.name,
|
||||
text: widget.manga.name!,
|
||||
isLoading: true,
|
||||
isComfortableGrid: true,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/views/manga/detail/manga_details_view.dart';
|
||||
import 'package:mangayomi/views/manga/detail/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/views/widgets/error_text.dart';
|
||||
|
|
@ -40,25 +41,33 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
|||
ref.watch(getMangaDetailStreamProvider(mangaId: widget.mangaId));
|
||||
return Scaffold(
|
||||
body: manga.when(
|
||||
data: (modelManga) {
|
||||
data: (manga) {
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
final mangaS = GetManga(
|
||||
genre: manga.genre!,
|
||||
author: manga.author,
|
||||
status: manga.status,
|
||||
chapters: manga.chapters.toList(),
|
||||
imageUrl: manga.imageUrl,
|
||||
description: manga.description,
|
||||
url: manga.link,
|
||||
name: manga.name,
|
||||
source: manga.source);
|
||||
bool isOk = false;
|
||||
ref
|
||||
.watch(getMangaDetailProvider(
|
||||
imageUrl: modelManga.imageUrl!,
|
||||
lang: modelManga.lang!,
|
||||
title: modelManga.name!,
|
||||
source: modelManga.source!,
|
||||
url: modelManga.link!)
|
||||
.future)
|
||||
manga: mangaS,
|
||||
lang: manga.lang!,
|
||||
source: manga.source!,
|
||||
).future)
|
||||
.then((value) async {
|
||||
if (value.chapters.isNotEmpty &&
|
||||
value.chapters.length > modelManga.chapters.length) {
|
||||
value.chapters.length > manga.chapters.length) {
|
||||
await isar.writeTxn(() async {
|
||||
int newChapsIndex =
|
||||
value.chapters.length - modelManga.chapters.length;
|
||||
modelManga.lastUpdate = DateTime.now().millisecondsSinceEpoch;
|
||||
value.chapters.length - manga.chapters.length;
|
||||
manga.lastUpdate = DateTime.now().millisecondsSinceEpoch;
|
||||
for (var i = 0; i < newChapsIndex; i++) {
|
||||
final chapters = Chapter(
|
||||
name: value.chapters[i].name,
|
||||
|
|
@ -68,8 +77,8 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
|||
scanlator: value.chapters[i].scanlator,
|
||||
isRead: false,
|
||||
lastPageRead: '',
|
||||
mangaId: modelManga.id)
|
||||
..manga.value = modelManga;
|
||||
mangaId: manga.id)
|
||||
..manga.value = manga;
|
||||
await isar.chapters.put(chapters);
|
||||
await chapters.manga.save();
|
||||
}
|
||||
|
|
@ -90,7 +99,7 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
|
|||
});
|
||||
},
|
||||
child: MangaDetailsView(
|
||||
manga: modelManga!,
|
||||
manga: manga!,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import 'package:go_router/go_router.dart';
|
|||
import 'package:mangayomi/models/manga_type.dart';
|
||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/sources/utils/utils.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/views/manga/home/manga_search_screen.dart';
|
||||
|
|
@ -39,7 +40,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
IconButton(
|
||||
onPressed: () {
|
||||
Map<String, String> data = {
|
||||
'url': getWpMangaUrl(widget.mangaType.source!),
|
||||
'url': getMangaBaseUrl(widget.mangaType.source!),
|
||||
'source': widget.mangaType.source!,
|
||||
};
|
||||
context.push("/mangawebview", extra: data);
|
||||
|
|
@ -54,7 +55,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
),
|
||||
body: getManga.when(
|
||||
data: (data) {
|
||||
if (data.url.isEmpty) {
|
||||
if (data.isEmpty) {
|
||||
return const Center(child: Text("No result"));
|
||||
}
|
||||
_scrollController.addListener(() {
|
||||
|
|
@ -91,9 +92,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
(value) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
data.url.addAll(value.url);
|
||||
data.name.addAll(value.name);
|
||||
data.image.addAll(value.image);
|
||||
data.addAll(value);
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
|
@ -103,9 +102,8 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
}
|
||||
}
|
||||
});
|
||||
final length = widget.mangaType.isFullData!
|
||||
? _fullDataLength
|
||||
: data.url.length;
|
||||
final length =
|
||||
widget.mangaType.isFullData! ? _fullDataLength : data.length;
|
||||
return Column(
|
||||
children: [
|
||||
Flexible(
|
||||
|
|
@ -117,9 +115,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
return _buildProgressIndicator();
|
||||
}
|
||||
return MangaHomeImageCard(
|
||||
url: data.url[index]!,
|
||||
name: data.name[index]!,
|
||||
image: data.image[index]!,
|
||||
manga: data[index]!,
|
||||
source: widget.mangaType.source!,
|
||||
lang: widget.mangaType.lang!,
|
||||
);
|
||||
|
|
@ -151,16 +147,12 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
}
|
||||
|
||||
class MangaHomeImageCard extends ConsumerStatefulWidget {
|
||||
final String image;
|
||||
final String url;
|
||||
final String name;
|
||||
final GetManga manga;
|
||||
final String source;
|
||||
final String lang;
|
||||
const MangaHomeImageCard({
|
||||
super.key,
|
||||
required this.url,
|
||||
required this.name,
|
||||
required this.image,
|
||||
required this.manga,
|
||||
required this.source,
|
||||
required this.lang,
|
||||
});
|
||||
|
|
@ -175,11 +167,7 @@ class _MangaHomeImageCardState extends ConsumerState<MangaHomeImageCard>
|
|||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final getMangaDetail = ref.watch(getMangaDetailProvider(
|
||||
source: widget.source,
|
||||
imageUrl: widget.image,
|
||||
title: widget.name,
|
||||
url: widget.url,
|
||||
lang: widget.lang));
|
||||
source: widget.source, manga: widget.manga, lang: widget.lang));
|
||||
|
||||
return getMangaDetail.when(
|
||||
data: (data) {
|
||||
|
|
@ -198,7 +186,7 @@ class _MangaHomeImageCardState extends ConsumerState<MangaHomeImageCard>
|
|||
),
|
||||
),
|
||||
BottomTextWidget(
|
||||
text: widget.name,
|
||||
text: widget.manga.name!,
|
||||
isLoading: true,
|
||||
)
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -114,14 +114,12 @@ class SearchResultScreen extends ConsumerWidget {
|
|||
),
|
||||
error: (error, stackTrace) => Center(child: Text(error.toString())),
|
||||
data: (data) {
|
||||
if (data.name.isNotEmpty) {
|
||||
if (data.isNotEmpty) {
|
||||
return GridViewWidget(
|
||||
itemCount: data.name.length,
|
||||
itemCount: data.length,
|
||||
itemBuilder: (context, index) {
|
||||
return MangaHomeImageCard(
|
||||
url: data.url[index]!,
|
||||
name: data.name[index]!,
|
||||
image: data.image[index]!,
|
||||
manga: data[index]!,
|
||||
source: source,
|
||||
lang: lang,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||
import 'package:mangayomi/sources/service/service.dart';
|
||||
import 'package:mangayomi/sources/service.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
||||
|
|
@ -15,7 +15,7 @@ class MangaImageCardWidget extends StatelessWidget {
|
|||
final String lang;
|
||||
final bool isLoading;
|
||||
|
||||
final GetMangaDetailModel? getMangaDetailModel;
|
||||
final GetManga? getMangaDetailModel;
|
||||
|
||||
const MangaImageCardWidget({
|
||||
required this.lang,
|
||||
|
|
|
|||
Loading…
Reference in a new issue