mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-21 16:01:58 +00:00
mangathemesia multi source , impl search feature
This commit is contained in:
parent
933ba5461c
commit
1ea161c615
20 changed files with 679 additions and 19 deletions
|
|
@ -10,7 +10,7 @@ import 'package:mangayomi/views/general/general_screen.dart';
|
||||||
import 'package:mangayomi/views/history/history_screen.dart';
|
import 'package:mangayomi/views/history/history_screen.dart';
|
||||||
import 'package:mangayomi/views/library/library_screen.dart';
|
import 'package:mangayomi/views/library/library_screen.dart';
|
||||||
import 'package:mangayomi/views/manga/detail/manga_reader_detail.dart';
|
import 'package:mangayomi/views/manga/detail/manga_reader_detail.dart';
|
||||||
import 'package:mangayomi/views/manga/home/home.dart';
|
import 'package:mangayomi/views/manga/home/mang_home_screen.dart';
|
||||||
import 'package:mangayomi/views/manga/reader/manga_reader_view.dart';
|
import 'package:mangayomi/views/manga/reader/manga_reader_view.dart';
|
||||||
import 'package:mangayomi/views/more/more_screen.dart';
|
import 'package:mangayomi/views/more/more_screen.dart';
|
||||||
import 'package:mangayomi/views/more/settings/appearance/appearance_screen.dart';
|
import 'package:mangayomi/views/more/settings/appearance/appearance_screen.dart';
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,9 @@ import 'package:http/http.dart' as http;
|
||||||
import 'package:html/dom.dart' as dom;
|
import 'package:html/dom.dart' as dom;
|
||||||
import 'package:mangayomi/models/model_manga.dart';
|
import 'package:mangayomi/models/model_manga.dart';
|
||||||
import 'package:mangayomi/providers/hive_provider.dart';
|
import 'package:mangayomi/providers/hive_provider.dart';
|
||||||
|
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||||
|
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
||||||
|
import 'package:mangayomi/source/source_model.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:flutter_js/flutter_js.dart';
|
import 'package:flutter_js/flutter_js.dart';
|
||||||
|
|
@ -37,6 +40,52 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
||||||
"${pathh!.path}/${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}/");
|
"${pathh!.path}/${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}/");
|
||||||
if (hiveUrl.isNotEmpty) {
|
if (hiveUrl.isNotEmpty) {
|
||||||
urll = hiveUrl;
|
urll = hiveUrl;
|
||||||
|
} else if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||||
|
final htmll =
|
||||||
|
await httpResToDom(url: modelManga.chapterUrl![index], headers: {});
|
||||||
|
|
||||||
|
if (htmll.querySelectorAll('#readerarea').isNotEmpty) {
|
||||||
|
final ta = htmll
|
||||||
|
.querySelectorAll('#readerarea')
|
||||||
|
.map((e) => e.outerHtml)
|
||||||
|
.toList();
|
||||||
|
final RegExp regex = RegExp(r'<img[^>]+src="([^"]+)"');
|
||||||
|
final Iterable<Match> matches = regex.allMatches(ta.first);
|
||||||
|
|
||||||
|
final List<String?> urls = matches.map((m) => m.group(1)).toList();
|
||||||
|
Iterable<Match> matchess = [];
|
||||||
|
if (htmll.querySelectorAll(' #select-paged ').isNotEmpty) {
|
||||||
|
final ee = htmll
|
||||||
|
.querySelectorAll(' #select-paged ')
|
||||||
|
.map((e) => e.outerHtml)
|
||||||
|
.toList();
|
||||||
|
final RegExp regexx = RegExp(r'value="([^"]+)"');
|
||||||
|
matchess = regexx.allMatches(ee.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String?> urlss = matchess.map((m) => m.group(1)).toList();
|
||||||
|
if (urls.length == 1 && urls.isNotEmpty) {
|
||||||
|
for (var i = 0; i < urlss.length; i++) {
|
||||||
|
if (urlss[i]!.length == 1) {
|
||||||
|
urll.add(
|
||||||
|
urls.first!.replaceAll("001", '00${int.parse(urlss[i]!) + 1}'));
|
||||||
|
} else if (urlss[i]!.length == 2) {
|
||||||
|
urll.add(
|
||||||
|
urls.first!.replaceAll("001", '0${int.parse(urlss[i]!) + 1}'));
|
||||||
|
} else if (urlss[i]!.length == 3) {
|
||||||
|
urll.add(
|
||||||
|
urls.first!.replaceAll("001", '${int.parse(urlss[i]!) + 1}'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (urls.length > 1 && urls.isNotEmpty) {
|
||||||
|
for (var tt in urls) {
|
||||||
|
urll.add(tt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ref.watch(hiveBoxMangaInfo).put(
|
||||||
|
"${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
|
||||||
|
urll);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/***********/
|
/***********/
|
||||||
/*mangahere*/
|
/*mangahere*/
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ part of 'get_manga_chapter_url.dart';
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getMangaChapterUrlHash() =>
|
String _$getMangaChapterUrlHash() =>
|
||||||
r'38cf836814df00df1a3a269c0c2fc0c85debff78';
|
r'a41949b68549e776832151d8b3a595db72fabdd9';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||||
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
||||||
|
import 'package:mangayomi/source/source_model.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_manga_detail.g.dart';
|
part 'get_manga_detail.g.dart';
|
||||||
|
|
||||||
|
|
@ -46,7 +48,130 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
||||||
List<String> chapterDate = [];
|
List<String> chapterDate = [];
|
||||||
source = source.toLowerCase();
|
source = source.toLowerCase();
|
||||||
String? description;
|
String? description;
|
||||||
if (source == "mangahere") {
|
if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||||
|
final dom = await httpResToDom(url: url, headers: {});
|
||||||
|
if (dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'div.bigcontent, div.animefull, div.main-info, div.postbody')
|
||||||
|
.isNotEmpty) {
|
||||||
|
final resHtml = dom.querySelector(
|
||||||
|
'div.bigcontent, div.animefull, div.main-info, div.postbody');
|
||||||
|
if (resHtml!.querySelectorAll('.tsinfo .imptdt').isNotEmpty) {
|
||||||
|
status = resHtml
|
||||||
|
.querySelectorAll('.tsinfo .imptdt')
|
||||||
|
.where((e) =>
|
||||||
|
e.innerHtml.contains("Status") ||
|
||||||
|
e.innerHtml.contains("Situação"))
|
||||||
|
.map((e) => e.innerHtml.contains("Situação")
|
||||||
|
? e.text.replaceAll('Situação', '').trim()
|
||||||
|
: e.text.replaceAll('Status', '').trim())
|
||||||
|
.toList()
|
||||||
|
.last;
|
||||||
|
} else if (resHtml.querySelectorAll('.infotable tr').isNotEmpty) {
|
||||||
|
status = resHtml
|
||||||
|
.querySelectorAll('.infotable tr')
|
||||||
|
.where((e) =>
|
||||||
|
e.innerHtml.toLowerCase().contains('statut') ||
|
||||||
|
e.innerHtml.toLowerCase().contains('status'))
|
||||||
|
.map((e) => e.querySelector('td:last-child')!.text)
|
||||||
|
.toList()
|
||||||
|
.first;
|
||||||
|
} else if (resHtml.querySelectorAll('.fmed').isNotEmpty) {
|
||||||
|
status = resHtml
|
||||||
|
.querySelectorAll('.tsinfo .imptdt')
|
||||||
|
.map((e) => e.text.replaceAll('Status', '').trim())
|
||||||
|
.toList()
|
||||||
|
.first;
|
||||||
|
} else {
|
||||||
|
status = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//2
|
||||||
|
if (resHtml.querySelectorAll('.fmed').isNotEmpty) {
|
||||||
|
author = resHtml
|
||||||
|
.querySelectorAll('.fmed')
|
||||||
|
.where((e) => e.innerHtml.contains("Author"))
|
||||||
|
.map((e) => e.text.replaceAll('Author', '').trim())
|
||||||
|
.toList()
|
||||||
|
.first;
|
||||||
|
} else if (resHtml.querySelectorAll('.tsinfo .imptdt').isNotEmpty) {
|
||||||
|
author = resHtml
|
||||||
|
.querySelectorAll('.tsinfo .imptdt')
|
||||||
|
.where((e) =>
|
||||||
|
e.innerHtml.contains("Author") ||
|
||||||
|
e.innerHtml.contains("Auteur") ||
|
||||||
|
e.innerHtml.contains("Autor"))
|
||||||
|
.map((e) => e.innerHtml.contains("Autor")
|
||||||
|
? e.text.replaceAll('Autor', '').trim()
|
||||||
|
: e.innerHtml.contains("Autheur")
|
||||||
|
? e.text.replaceAll('Auteur', '').trim()
|
||||||
|
: e.text.replaceAll('Author', '').trim())
|
||||||
|
.toList()
|
||||||
|
.first;
|
||||||
|
} else if (resHtml.querySelectorAll('.infotable tr').isNotEmpty) {
|
||||||
|
author = resHtml
|
||||||
|
.querySelectorAll('.infotable tr')
|
||||||
|
.where((e) =>
|
||||||
|
e.innerHtml.toLowerCase().contains('auteur') ||
|
||||||
|
e.innerHtml.toLowerCase().contains('author'))
|
||||||
|
.map((e) => e.querySelector('td:last-child')!.text)
|
||||||
|
.toList()
|
||||||
|
.first;
|
||||||
|
} else {
|
||||||
|
author = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
description = resHtml
|
||||||
|
.querySelector(".desc, .entry-content[itemprop=description]")!
|
||||||
|
.text;
|
||||||
|
if (resHtml
|
||||||
|
.querySelectorAll('div.gnr a, .mgen a, .seriestugenre a')
|
||||||
|
.isNotEmpty) {
|
||||||
|
final tt = resHtml
|
||||||
|
.querySelectorAll('div.gnr a, .mgen a, .seriestugenre a')
|
||||||
|
.map((e) => e.text.trim())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (var ok in tt) {
|
||||||
|
genre.add(ok);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
genre.add('');
|
||||||
|
}
|
||||||
|
if (resHtml.querySelectorAll('#chapterlist a').isNotEmpty) {
|
||||||
|
final udl = resHtml
|
||||||
|
.querySelectorAll('#chapterlist a ')
|
||||||
|
.where((e) => e.attributes.containsKey('href'))
|
||||||
|
.map((e) => e.attributes['href'])
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (var ok in udl) {
|
||||||
|
chapterUrl.add(ok!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resHtml.querySelectorAll('.lch a, .chapternum').isNotEmpty) {
|
||||||
|
final tt = resHtml
|
||||||
|
.querySelectorAll('.lch a, .chapternum')
|
||||||
|
.map((e) => e.text.trim())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
tt.removeWhere((element) => element.contains('{{number}}'));
|
||||||
|
for (var ok in tt) {
|
||||||
|
chapterTitle.add(ok.trimLeft());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resHtml.querySelectorAll('.chapterdate').isNotEmpty) {
|
||||||
|
final tt = resHtml
|
||||||
|
.querySelectorAll('.chapterdate')
|
||||||
|
.map((e) => e.text.trim())
|
||||||
|
.toList();
|
||||||
|
tt.removeWhere((element) => element.contains('{{date}}'));
|
||||||
|
for (var ok in tt) {
|
||||||
|
chapterDate.add(ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (source == "mangahere") {
|
||||||
final dom = await httpResToDom(
|
final dom = await httpResToDom(
|
||||||
url: "http://www.mangahere.cc$url",
|
url: "http://www.mangahere.cc$url",
|
||||||
headers: {
|
headers: {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_manga_detail.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getMangaDetailHash() => r'bbaec699742fa0b06f698d9c3be501564d9a9352';
|
String _$getMangaDetailHash() => r'4b0dd5315b3a1270722494045a7f9e3a3f455484';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
||||||
|
import 'package:mangayomi/source/source_list.dart';
|
||||||
|
import 'package:mangayomi/source/source_model.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
part 'get_popular_manga.g.dart';
|
part 'get_popular_manga.g.dart';
|
||||||
|
|
||||||
|
|
@ -14,6 +16,26 @@ class GetMangaModel {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getWpMangaUrl(String source) {
|
||||||
|
String url = "";
|
||||||
|
for (var i = 0; i < sourcesList.length; i++) {
|
||||||
|
if (sourcesList[i].sourceName.toLowerCase() == source.toLowerCase()) {
|
||||||
|
url = sourcesList[i].url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeSource getWpMangTypeSource(String source) {
|
||||||
|
TypeSource? typeSource;
|
||||||
|
for (var i = 0; i < sourcesList.length; i++) {
|
||||||
|
if (sourcesList[i].sourceName.toLowerCase() == source.toLowerCase()) {
|
||||||
|
typeSource = sourcesList[i].typeSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return typeSource!;
|
||||||
|
}
|
||||||
|
|
||||||
@riverpod
|
@riverpod
|
||||||
Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
||||||
{required String source, required int page}) async {
|
{required String source, required int page}) async {
|
||||||
|
|
@ -21,6 +43,46 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
||||||
List<String?> name = [];
|
List<String?> name = [];
|
||||||
List<String?> image = [];
|
List<String?> image = [];
|
||||||
source = source.toLowerCase();
|
source = source.toLowerCase();
|
||||||
|
if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||||
|
final dom = await httpResToDom(
|
||||||
|
url: '${getWpMangaUrl(source)}/manga/?title=&page=$page&order=popular',
|
||||||
|
headers: {});
|
||||||
|
|
||||||
|
if (dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'.utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx')
|
||||||
|
.isNotEmpty) {
|
||||||
|
url = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'.utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx')
|
||||||
|
.map((e) {
|
||||||
|
RegExp exp = RegExp(r'href="([^"]+)"');
|
||||||
|
Iterable<Match> matches = exp.allMatches(e.innerHtml);
|
||||||
|
String? firstMatch = matches.first.group(1);
|
||||||
|
return firstMatch;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
image = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'.utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx')
|
||||||
|
.map((e) {
|
||||||
|
RegExp exp = RegExp(r'src="([^"]+)"');
|
||||||
|
Iterable<Match> matches = exp.allMatches(e.innerHtml);
|
||||||
|
String? firstMatch = matches.first.group(1);
|
||||||
|
return firstMatch;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
name = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'.utao .uta .imgu, .listupd .bs .bsx, .listo .bs .bsx ')
|
||||||
|
.map((e) {
|
||||||
|
RegExp exp = RegExp(r'title="([^"]+)"');
|
||||||
|
Iterable<Match> matches = exp.allMatches(e.innerHtml);
|
||||||
|
String? firstMatch = matches.first.group(1);
|
||||||
|
return firstMatch;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
} else
|
||||||
//mangahere
|
//mangahere
|
||||||
if (source == "mangahere") {
|
if (source == "mangahere") {
|
||||||
final dom = await httpResToDom(
|
final dom = await httpResToDom(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ part of 'get_popular_manga.dart';
|
||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$getPopularMangaHash() => r'0b6445ff81dbbe1d337f37ed46544f5834805088';
|
String _$getPopularMangaHash() => r'5addb8826c01045b532a53de957c6470294833ad';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|
|
||||||
96
lib/services/search_manga.dart
Normal file
96
lib/services/search_manga.dart
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:html/dom.dart' as dom;
|
||||||
|
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||||
|
import 'package:mangayomi/services/http_res_to_dom_html.dart';
|
||||||
|
import 'package:mangayomi/source/source_model.dart';
|
||||||
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
part 'search_manga.g.dart';
|
||||||
|
|
||||||
|
class SearchMangaModel {
|
||||||
|
late List<String?> url;
|
||||||
|
late List<String?> name;
|
||||||
|
late List<String?> image;
|
||||||
|
|
||||||
|
SearchMangaModel({
|
||||||
|
required this.name,
|
||||||
|
required this.url,
|
||||||
|
required this.image,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@riverpod
|
||||||
|
Future<SearchMangaModel> searchManga(SearchMangaRef ref,
|
||||||
|
{required String source, required String query}) async {
|
||||||
|
List<String?> url = [];
|
||||||
|
List<String?> name = [];
|
||||||
|
List<String?> image = [];
|
||||||
|
source = source.toLowerCase();
|
||||||
|
//mangathemesia
|
||||||
|
if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||||
|
final dom = await httpResToDom(
|
||||||
|
url: '${getWpMangaUrl(source)}/?s=${query.trim()}', headers: {});
|
||||||
|
|
||||||
|
if (dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'#content > div > div.postbody > div > div.listupd > div > div > a')
|
||||||
|
.isNotEmpty) {
|
||||||
|
url = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'#content > div > div.postbody > div > div.listupd > div > div > a ')
|
||||||
|
.where((e) => e.attributes.containsKey('href'))
|
||||||
|
.map((e) => e.attributes['href'])
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
image = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
' #content > div > div.postbody > div > div.listupd > div > div > a > div > img')
|
||||||
|
.where((e) => e.attributes.containsKey('src'))
|
||||||
|
.map((e) => e.attributes['src'])
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
name = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'#content > div > div.postbody > div > div.listupd > div > div > a ')
|
||||||
|
.where((e) => e.attributes.containsKey('title'))
|
||||||
|
.map((e) => e.attributes['title'])
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//mangahere
|
||||||
|
else if (source == "mangahere") {
|
||||||
|
log("message");
|
||||||
|
final dom = await httpResToDom(
|
||||||
|
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',
|
||||||
|
headers: {});
|
||||||
|
if (dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'body > div.container > div > div > ul > li > p.manga-list-4-item-title > a')
|
||||||
|
.isNotEmpty) {
|
||||||
|
url = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'body > div.container > div > div > ul > li > p.manga-list-4-item-title > a')
|
||||||
|
.where((e) => e.attributes.containsKey('href'))
|
||||||
|
.map((e) => e.attributes['href'])
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
image = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'body > div.container > div > div > ul > li > a > img')
|
||||||
|
.where((e) => e.attributes.containsKey('src'))
|
||||||
|
.where((e) => e.attributes['src']!.contains("cover"))
|
||||||
|
.map((e) => e.attributes['src'])
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
name = dom
|
||||||
|
.querySelectorAll(
|
||||||
|
'body > div.container > div > div > ul > li > p.manga-list-4-item-title > a')
|
||||||
|
.where((e) => e.attributes.containsKey('title'))
|
||||||
|
.map((e) => e.attributes['title'])
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SearchMangaModel(name: name, url: url, image: image);
|
||||||
|
}
|
||||||
121
lib/services/search_manga.g.dart
Normal file
121
lib/services/search_manga.g.dart
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'search_manga.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// RiverpodGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
String _$searchMangaHash() => r'18866e3523f085404fecaa91fa3bc1a7149724e6';
|
||||||
|
|
||||||
|
/// Copied from Dart SDK
|
||||||
|
class _SystemHash {
|
||||||
|
_SystemHash._();
|
||||||
|
|
||||||
|
static int combine(int hash, int value) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + value);
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||||
|
return hash ^ (hash >> 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finish(int hash) {
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
hash = hash ^ (hash >> 11);
|
||||||
|
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef SearchMangaRef = AutoDisposeFutureProviderRef<SearchMangaModel>;
|
||||||
|
|
||||||
|
/// See also [searchManga].
|
||||||
|
@ProviderFor(searchManga)
|
||||||
|
const searchMangaProvider = SearchMangaFamily();
|
||||||
|
|
||||||
|
/// See also [searchManga].
|
||||||
|
class SearchMangaFamily extends Family<AsyncValue<SearchMangaModel>> {
|
||||||
|
/// See also [searchManga].
|
||||||
|
const SearchMangaFamily();
|
||||||
|
|
||||||
|
/// See also [searchManga].
|
||||||
|
SearchMangaProvider call({
|
||||||
|
required String source,
|
||||||
|
required String query,
|
||||||
|
}) {
|
||||||
|
return SearchMangaProvider(
|
||||||
|
source: source,
|
||||||
|
query: query,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
SearchMangaProvider getProviderOverride(
|
||||||
|
covariant SearchMangaProvider provider,
|
||||||
|
) {
|
||||||
|
return call(
|
||||||
|
source: provider.source,
|
||||||
|
query: provider.query,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||||
|
_allTransitiveDependencies;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get name => r'searchMangaProvider';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [searchManga].
|
||||||
|
class SearchMangaProvider extends AutoDisposeFutureProvider<SearchMangaModel> {
|
||||||
|
/// See also [searchManga].
|
||||||
|
SearchMangaProvider({
|
||||||
|
required this.source,
|
||||||
|
required this.query,
|
||||||
|
}) : super.internal(
|
||||||
|
(ref) => searchManga(
|
||||||
|
ref,
|
||||||
|
source: source,
|
||||||
|
query: query,
|
||||||
|
),
|
||||||
|
from: searchMangaProvider,
|
||||||
|
name: r'searchMangaProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$searchMangaHash,
|
||||||
|
dependencies: SearchMangaFamily._dependencies,
|
||||||
|
allTransitiveDependencies:
|
||||||
|
SearchMangaFamily._allTransitiveDependencies,
|
||||||
|
);
|
||||||
|
|
||||||
|
final String source;
|
||||||
|
final String query;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is SearchMangaProvider &&
|
||||||
|
other.source == source &&
|
||||||
|
other.query == query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, source.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, query.hashCode);
|
||||||
|
|
||||||
|
return _SystemHash.finish(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ignore_for_file: unnecessary_raw_strings, subtype_of_sealed_class, invalid_use_of_internal_member, do_not_use_environment, prefer_const_constructors, public_member_api_docs, avoid_private_typedef_functions
|
||||||
|
|
@ -378,4 +378,53 @@ List<SourceModel> sourcesList = [
|
||||||
typeSource: TypeSource.mangathemesia,
|
typeSource: TypeSource.mangathemesia,
|
||||||
logoUrl:
|
logoUrl:
|
||||||
'https://xcalibrscans.com/wp-content/uploads/2021/06/xcalibr-dark-v3.png'),
|
'https://xcalibrscans.com/wp-content/uploads/2021/06/xcalibr-dark-v3.png'),
|
||||||
|
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "Fallen Angels",
|
||||||
|
url: "https://manga.fascans.com",
|
||||||
|
lang: "en",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "Scan FR",
|
||||||
|
url: "https://www.scan-fr.org",
|
||||||
|
lang: "fr",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "Scan VF",
|
||||||
|
url: "https://www.scan-vf.net",
|
||||||
|
lang: "fr",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''), //
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "Komikid",
|
||||||
|
url: "https://www.komikid.com",
|
||||||
|
lang: "id",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "MangaHanta",
|
||||||
|
url: "http://mangahanta.com",
|
||||||
|
lang: "tr",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "MangaID",
|
||||||
|
url: "https://mangaid.click",
|
||||||
|
lang: "id",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "Jpmangas",
|
||||||
|
url: "https://jpmangas.cc",
|
||||||
|
lang: "fr",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
|
SourceModel(
|
||||||
|
sourceName: "FR Scan",
|
||||||
|
url: "https://frscan.ws",
|
||||||
|
lang: "fr",
|
||||||
|
typeSource: TypeSource.mmrcms,
|
||||||
|
logoUrl: ''),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,9 @@ enum TypeSource {
|
||||||
@HiveField(2)
|
@HiveField(2)
|
||||||
mangathemesia,
|
mangathemesia,
|
||||||
@HiveField(3)
|
@HiveField(3)
|
||||||
comick
|
comick,
|
||||||
|
@HiveField(4)
|
||||||
|
mmrcms
|
||||||
}
|
}
|
||||||
|
|
||||||
// @HiveType(typeId: 3)
|
// @HiveType(typeId: 3)
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,8 @@ class TypeSourceAdapter extends TypeAdapter<TypeSource> {
|
||||||
return TypeSource.mangathemesia;
|
return TypeSource.mangathemesia;
|
||||||
case 3:
|
case 3:
|
||||||
return TypeSource.comick;
|
return TypeSource.comick;
|
||||||
|
case 4:
|
||||||
|
return TypeSource.mmrcms;
|
||||||
default:
|
default:
|
||||||
return TypeSource.single;
|
return TypeSource.single;
|
||||||
}
|
}
|
||||||
|
|
@ -94,6 +96,9 @@ class TypeSourceAdapter extends TypeAdapter<TypeSource> {
|
||||||
case TypeSource.comick:
|
case TypeSource.comick:
|
||||||
writer.writeByte(3);
|
writer.writeByte(3);
|
||||||
break;
|
break;
|
||||||
|
case TypeSource.mmrcms:
|
||||||
|
writer.writeByte(4);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
22
lib/utils/headers.dart
Normal file
22
lib/utils/headers.dart
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
Map<String, String>? headers(String source) {
|
||||||
|
return source == 'japscan'
|
||||||
|
? {
|
||||||
|
'referer': 'https://www.japscan.lol/',
|
||||||
|
}
|
||||||
|
: source == 'mangakawaii'
|
||||||
|
? {
|
||||||
|
'Referer': 'https://www.mangakawaii.io/',
|
||||||
|
'User-Agent':
|
||||||
|
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/8\$userAgentRandomizer1.0.4\$userAgentRandomizer3.1\$userAgentRandomizer2 Safari/537.36',
|
||||||
|
'Accept-Language': 'fr'
|
||||||
|
}
|
||||||
|
: source == 'mangahere'
|
||||||
|
? {"Referer": "https://www.mangahere.cc/", "Cookie": "isAdult=1"}
|
||||||
|
: source == 'comick'
|
||||||
|
? {
|
||||||
|
'Referer': 'https://comick.app/',
|
||||||
|
'User-Agent':
|
||||||
|
'Tachiyomi Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/8\\\$userAgentRandomizer1.0.4\\\$userAgentRandomizer3.1\\\$userAgentRandomizer2 Safari/537.36'
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
}
|
||||||
|
|
@ -63,6 +63,7 @@ class _BrowseScreenState extends State<BrowseScreen>
|
||||||
_isSearch = false;
|
_isSearch = false;
|
||||||
});
|
});
|
||||||
_textEditingController.clear();
|
_textEditingController.clear();
|
||||||
|
entriesFilter = entries;
|
||||||
},
|
},
|
||||||
controller: _textEditingController,
|
controller: _textEditingController,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
||||||
setState(() {
|
setState(() {
|
||||||
isSearch = false;
|
isSearch = false;
|
||||||
});
|
});
|
||||||
|
_textEditingController.clear();
|
||||||
|
|
||||||
},
|
},
|
||||||
controller: _textEditingController,
|
controller: _textEditingController,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:mangayomi/models/manga_type.dart';
|
import 'package:mangayomi/models/manga_type.dart';
|
||||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||||
import 'package:mangayomi/services/get_popular_manga.dart';
|
import 'package:mangayomi/services/get_popular_manga.dart';
|
||||||
|
import 'package:mangayomi/views/manga/home/manga_search_screen.dart';
|
||||||
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
||||||
import 'package:mangayomi/views/widgets/cover_view_widget.dart';
|
import 'package:mangayomi/views/widgets/cover_view_widget.dart';
|
||||||
import 'package:mangayomi/views/widgets/gridview_widget.dart';
|
import 'package:mangayomi/views/widgets/gridview_widget.dart';
|
||||||
|
|
@ -29,7 +30,10 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('${widget.mangaType.source}'),
|
title: Text('${widget.mangaType.source}'),
|
||||||
actions: [],
|
actions: [
|
||||||
|
MangaSearchButton(
|
||||||
|
source: widget.mangaType.source!, lang: widget.mangaType.lang!)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: getManga.when(
|
body: getManga.when(
|
||||||
data: (data) {
|
data: (data) {
|
||||||
128
lib/views/manga/home/manga_search_screen.dart
Normal file
128
lib/views/manga/home/manga_search_screen.dart
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:mangayomi/services/search_manga.dart';
|
||||||
|
import 'package:mangayomi/views/manga/home/mang_home_screen.dart';
|
||||||
|
import 'package:mangayomi/views/widgets/gridview_widget.dart';
|
||||||
|
|
||||||
|
class MangaSearchButton extends StatelessWidget {
|
||||||
|
final String source;
|
||||||
|
final String lang;
|
||||||
|
MangaSearchButton({super.key, required this.source, required this.lang});
|
||||||
|
|
||||||
|
late final CustomSearchDelegate _delegate =
|
||||||
|
CustomSearchDelegate(source, lang);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: const Icon(Icons.search),
|
||||||
|
onPressed: () async {
|
||||||
|
await showSearch<dynamic>(
|
||||||
|
context: context,
|
||||||
|
delegate: _delegate,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomSearchDelegate extends SearchDelegate {
|
||||||
|
final String source;
|
||||||
|
final String lang;
|
||||||
|
CustomSearchDelegate(this.source, this.lang);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildLeading(BuildContext context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: const BackButtonIcon(),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildSuggestions(BuildContext context) {
|
||||||
|
return Container();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget buildResults(BuildContext context) {
|
||||||
|
if (query.isEmpty) {
|
||||||
|
return const Center(child: Text("Empty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SearchResult(
|
||||||
|
query: query,
|
||||||
|
source: source,
|
||||||
|
lang: lang,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Widget>? buildActions(BuildContext context) {
|
||||||
|
if (query.isNotEmpty) {
|
||||||
|
return [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () {
|
||||||
|
query = '';
|
||||||
|
},
|
||||||
|
),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ThemeData appBarTheme(BuildContext context) {
|
||||||
|
final ThemeData theme = Theme.of(context);
|
||||||
|
return theme.copyWith(
|
||||||
|
appBarTheme: const AppBarTheme(),
|
||||||
|
inputDecorationTheme: const InputDecorationTheme(hintStyle: TextStyle()),
|
||||||
|
textTheme: theme.textTheme
|
||||||
|
.copyWith(titleLarge: theme.textTheme.titleLarge!.copyWith()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SearchResult extends ConsumerWidget {
|
||||||
|
final String query;
|
||||||
|
final String source;
|
||||||
|
final String lang;
|
||||||
|
const SearchResult({
|
||||||
|
super.key,
|
||||||
|
required this.query,
|
||||||
|
required this.source,
|
||||||
|
required this.lang,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final search = ref.watch(searchMangaProvider(source: source, query: query));
|
||||||
|
return search.when(
|
||||||
|
loading: () => const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
error: (error, stackTrace) => const Center(child: Text("Error")),
|
||||||
|
data: (data) {
|
||||||
|
if (data.name.isNotEmpty) {
|
||||||
|
return GridViewWidget(
|
||||||
|
itemCount: data.name.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return MangaHomeImageCard(
|
||||||
|
url: data.url[index]!,
|
||||||
|
name: data.name[index]!,
|
||||||
|
image: data.image[index]!,
|
||||||
|
source: source,
|
||||||
|
lang: lang,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const Center(
|
||||||
|
child: Text("Empty"),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:extended_image/extended_image.dart';
|
import 'package:extended_image/extended_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
|
|
||||||
class ImageViewHorizontal extends StatefulWidget {
|
class ImageViewHorizontal extends StatefulWidget {
|
||||||
final int length;
|
final int length;
|
||||||
|
|
@ -43,10 +44,7 @@ class _ImageViewHorizontalState extends State<ImageViewHorizontal> {
|
||||||
clearMemoryCacheWhenDispose: true,
|
clearMemoryCacheWhenDispose: true,
|
||||||
enableMemoryCache: false,
|
enableMemoryCache: false,
|
||||||
cacheMaxAge: const Duration(days: 7),
|
cacheMaxAge: const Duration(days: 7),
|
||||||
headers: const {
|
headers: headers(widget.source),
|
||||||
"Referer": "https://www.mangahere.cc/",
|
|
||||||
"Cookie": "isAdult=1"
|
|
||||||
},
|
|
||||||
mode: ExtendedImageMode.gesture,
|
mode: ExtendedImageMode.gesture,
|
||||||
initGestureConfigHandler: widget.initGestureConfigHandler,
|
initGestureConfigHandler: widget.initGestureConfigHandler,
|
||||||
onDoubleTap: widget.onDoubleTap,
|
onDoubleTap: widget.onDoubleTap,
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import 'package:extended_image/extended_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
import 'package:mangayomi/utils/media_query.dart';
|
import 'package:mangayomi/utils/media_query.dart';
|
||||||
|
|
||||||
class ImageViewVertical extends ConsumerStatefulWidget {
|
class ImageViewVertical extends ConsumerStatefulWidget {
|
||||||
|
|
@ -44,10 +45,7 @@ class _ImageViewVerticalState extends ConsumerState<ImageViewVertical>
|
||||||
height: MediaQuery.of(context).padding.top,
|
height: MediaQuery.of(context).padding.top,
|
||||||
),
|
),
|
||||||
ExtendedImage.network(widget.url,
|
ExtendedImage.network(widget.url,
|
||||||
headers: const {
|
headers: headers(widget.source),
|
||||||
"Referer": "https://www.mangahere.cc/",
|
|
||||||
"Cookie": "isAdult=1"
|
|
||||||
},
|
|
||||||
handleLoadingProgress: true,
|
handleLoadingProgress: true,
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
cacheMaxAge: const Duration(days: 7),
|
cacheMaxAge: const Duration(days: 7),
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
|
||||||
import 'package:mangayomi/models/model_manga.dart';
|
import 'package:mangayomi/models/model_manga.dart';
|
||||||
import 'package:mangayomi/services/get_manga_detail.dart';
|
import 'package:mangayomi/services/get_manga_detail.dart';
|
||||||
import 'package:mangayomi/utils/cached_network.dart';
|
import 'package:mangayomi/utils/cached_network.dart';
|
||||||
|
import 'package:mangayomi/utils/headers.dart';
|
||||||
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
||||||
import 'package:mangayomi/views/widgets/cover_view_widget.dart';
|
import 'package:mangayomi/views/widgets/cover_view_widget.dart';
|
||||||
|
|
||||||
|
|
@ -50,10 +51,7 @@ class _MangaImageCardWidgetState extends ConsumerState<MangaImageCardWidget> {
|
||||||
},
|
},
|
||||||
child: CoverViewWidget(children: [
|
child: CoverViewWidget(children: [
|
||||||
cachedNetworkImage(
|
cachedNetworkImage(
|
||||||
headers: {
|
headers: headers(widget.getMangaDetailModel!.source!),
|
||||||
"Referer": "https://www.mangahere.cc/",
|
|
||||||
"Cookie": "isAdult=1"
|
|
||||||
},
|
|
||||||
imageUrl: widget.getMangaDetailModel!.imageUrl!,
|
imageUrl: widget.getMangaDetailModel!.imageUrl!,
|
||||||
width: 200,
|
width: 200,
|
||||||
height: 270,
|
height: 270,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue