mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-04-20 23:22:07 +00:00
mangagere http header fix & add comick scanlator
This commit is contained in:
parent
a06e320e49
commit
0d7fbf3ca6
17 changed files with 294 additions and 135 deletions
|
|
@ -35,7 +35,7 @@ class Chapters {
|
|||
String? updatedAt;
|
||||
int? upCount;
|
||||
int? downCount;
|
||||
List<String>? groupName;
|
||||
List<dynamic>? groupName;
|
||||
String? hid;
|
||||
List<MdGroups>? mdGroups;
|
||||
|
||||
|
|
@ -65,6 +65,7 @@ class Chapters {
|
|||
// updatedAt = json['updated_at'];
|
||||
// upCount = json['up_count'];
|
||||
// downCount = json['down_count'];
|
||||
groupName = json['group_name'] ?? [];
|
||||
hid = json['hid'];
|
||||
// if (json['md_groups'] != null) {
|
||||
// mdGroups = <MdGroups>[];
|
||||
|
|
|
|||
|
|
@ -76,9 +76,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
final decoded = utf8.decode(base64.decode(unscrambledData));
|
||||
final data = jsonDecode(decoded);
|
||||
urll = data["imagesLink"].map((it) => it).toList();
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
} catch (_) {}
|
||||
}
|
||||
isOk = true;
|
||||
|
|
@ -112,11 +109,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
for (var url in page.chapter!.images!) {
|
||||
urll.add(url.url);
|
||||
}
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
}
|
||||
/*************/
|
||||
/*mangathemesia*/
|
||||
|
|
@ -164,11 +156,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
urll.add(tt);
|
||||
}
|
||||
}
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,11 +184,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
urll.add(
|
||||
'https://cdn.mangakawaii.pics/uploads/manga/$mangaSlug/chapters_fr/$chapterSlug/$tt');
|
||||
}
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
}
|
||||
|
||||
/***********/
|
||||
|
|
@ -232,12 +214,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
.group(1)!
|
||||
.replaceAll(RegExp(r"\s+\b|\b\s"), "");
|
||||
}).toList();
|
||||
// log(message)
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,11 +325,6 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
}
|
||||
|
||||
flutterJs.dispose();
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
}
|
||||
} else if (source == 'japscan') {
|
||||
final response = await httpGet(
|
||||
|
|
@ -376,6 +347,11 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
|
|||
});
|
||||
}
|
||||
if (urll.isNotEmpty) {
|
||||
if (!incognitoMode) {
|
||||
ref.watch(hiveBoxMangaInfoProvider).put(
|
||||
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
|
||||
urll);
|
||||
}
|
||||
for (var i = 0; i < urll.length; i++) {
|
||||
if (await File("${path!.path}" "${padIndex(i + 1)}.jpg").exists()) {
|
||||
isLocaleList.add(true);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:mangayomi/services/get_popular_manga.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/source/source_model.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/reg_exp_matcher.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
part 'get_manga_detail.g.dart';
|
||||
|
|
@ -51,15 +52,10 @@ _parseStatut(int i) {
|
|||
}
|
||||
|
||||
Future findCurrentSlug(String oldSlug) async {
|
||||
var headers = {
|
||||
'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'
|
||||
};
|
||||
var request = http.Request('GET',
|
||||
Uri.parse('https://api.comick.fun/tachiyomi/mapping?slugs=$oldSlug'));
|
||||
|
||||
request.headers.addAll(headers);
|
||||
request.headers.addAll(headers("comick"));
|
||||
|
||||
http.StreamedResponse response = await request.send();
|
||||
|
||||
|
|
@ -89,6 +85,7 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
|||
List<String> chapterDate = [];
|
||||
String? description;
|
||||
List<ModelChapters> chapters = [];
|
||||
List<String> scanlators = [];
|
||||
/********/
|
||||
/*comick*/
|
||||
/********/
|
||||
|
|
@ -123,27 +120,30 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
|||
'https://api.comick.fun/comic/$mangaId/chapters?lang=$lang&limit=$limit',
|
||||
source: source,
|
||||
resDom: false) as String?;
|
||||
List<String> chapterTitles = [];
|
||||
List<String> chapterUrls = [];
|
||||
List<String> chapterDates = [];
|
||||
// List<String> chapterTitles = [];
|
||||
// List<String> chapterUrls = [];
|
||||
// List<String> chapterDates = [];
|
||||
var chapterDetail = jsonDecode(responsee!) as Map<String, dynamic>;
|
||||
var chapterDetailMap = MangaChapterModelComick.fromJson(chapterDetail);
|
||||
for (var chapter in chapterDetailMap.chapters!) {
|
||||
chapterUrls.add(
|
||||
scanlators.add(chapter.groupName!.isNotEmpty
|
||||
? chapter.groupName!.first.toString() != 'null'
|
||||
? chapter.groupName!.first
|
||||
: ""
|
||||
: "");
|
||||
// print(chapter.groupName!);
|
||||
chapterUrl.add(
|
||||
"/comic/${mangaDetailLMap.comic!.slug}/${chapter.hid}-chapter-${chapter.chap}-en");
|
||||
chapterDates.add(chapter.createdAt!.toString().substring(0, 10));
|
||||
chapterTitles.add(beautifyChapterName(
|
||||
chapterDate.add(chapter.createdAt!.toString().substring(0, 10));
|
||||
chapterTitle.add(beautifyChapterName(
|
||||
chapter.vol ?? "", chapter.chap ?? "", chapter.title ?? "", lang));
|
||||
}
|
||||
List<String> chapterTitless = [];
|
||||
for (var i = 0; i < chapterTitles.length; i++) {
|
||||
if (!chapterTitless.contains(chapterTitles[i])) {
|
||||
chapterTitle.add(chapterTitles[i]);
|
||||
chapterUrl.add(chapterUrls[i]);
|
||||
chapterDate.add(chapterDates[i].replaceAll('-', "/"));
|
||||
}
|
||||
chapterTitless.add(chapterTitles[i]);
|
||||
}
|
||||
// List<String> chapterTitless = [];
|
||||
// for (var i = 0; i < chapterTitles.length; i++) {
|
||||
// chapterTitle.add(chapterTitles[i]);
|
||||
// chapterUrl.add(chapterUrls[i]);
|
||||
// chapterDate.add(chapterDates[i].replaceAll('-', "/"));
|
||||
// }
|
||||
}
|
||||
/*************/
|
||||
/*mangathemesia*/
|
||||
|
|
@ -667,7 +667,7 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
|
|||
url: chapterUrl[i],
|
||||
dateUpload: chapterDate[i],
|
||||
isBookmarked: false,
|
||||
scanlator: "",
|
||||
scanlator: scanlators.isEmpty ? "" : scanlators[i],
|
||||
isRead: false,
|
||||
lastPageRead: ''));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
|||
/*mangathemesia*/
|
||||
/**************/
|
||||
if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
|
||||
final dom = await httpGet(useUserAgent: true,
|
||||
final dom = await httpGet(
|
||||
useUserAgent: true,
|
||||
url: '${getWpMangaUrl(source)}/manga/?title=&page=$page&order=popular',
|
||||
source: source,
|
||||
resDom: true) as Document?;
|
||||
|
|
@ -198,7 +199,7 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
|||
' body > div.container.weekrank.ranking > div > div > ul > li > a > img')
|
||||
.where((e) => e.attributes.containsKey('src'))
|
||||
.where((e) => e.attributes['src']!.contains("cover"))
|
||||
.map((e) => e.attributes['src']!.split('?').first)
|
||||
.map((e) => e.attributes['src'])
|
||||
.toList();
|
||||
|
||||
name = dom
|
||||
|
|
@ -208,7 +209,11 @@ Future<GetMangaModel> getPopularManga(GetPopularMangaRef ref,
|
|||
.map((e) => e.attributes['title'])
|
||||
.toList();
|
||||
}
|
||||
} else if (source == "japscan") {
|
||||
}
|
||||
/***********/
|
||||
/*japscan*/
|
||||
/***********/
|
||||
else if (source == "japscan") {
|
||||
final dom = await httpGet(
|
||||
url: "https://www.japscan.lol/",
|
||||
source: source,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import 'package:flutter/foundation.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget cachedNetworkImage(
|
||||
{Map<String, String>? headers,
|
||||
{required Map<String, String>? headers,
|
||||
required String imageUrl,
|
||||
required double? width,
|
||||
required double? height,
|
||||
|
|
|
|||
|
|
@ -33,5 +33,5 @@ Map<String, String> headers(String source) {
|
|||
'Referer': "https://www.sushscan.net/",
|
||||
"Cookie": cookie
|
||||
}
|
||||
: {'User-Agent': userAgent, "Cookie": cookie};
|
||||
: {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:mangayomi/models/manga_reader.dart';
|
|||
import 'package:mangayomi/providers/hive_provider.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/views/library/search_text_form_field.dart';
|
||||
|
||||
class HistoryScreen extends ConsumerStatefulWidget {
|
||||
|
|
@ -93,7 +94,9 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> {
|
|||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
ref.watch(hiveBoxMangaHistoryProvider).clear();
|
||||
ref
|
||||
.watch(hiveBoxMangaHistoryProvider)
|
||||
.clear();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: const Text("Ok")),
|
||||
|
|
@ -146,6 +149,7 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> {
|
|||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
child: cachedNetworkImage(
|
||||
headers: headers(element.modelManga.source!),
|
||||
imageUrl: element.modelManga.imageUrl!,
|
||||
width: 60,
|
||||
height: 90,
|
||||
|
|
@ -155,8 +159,9 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> {
|
|||
),
|
||||
Flexible(
|
||||
child: ValueListenableBuilder<Box>(
|
||||
valueListenable:
|
||||
ref.watch(hiveBoxMangaInfoProvider).listenable(),
|
||||
valueListenable: ref
|
||||
.watch(hiveBoxMangaInfoProvider)
|
||||
.listenable(),
|
||||
builder: (context, value, child) {
|
||||
final values = value.get(
|
||||
"${element.modelManga.lang}-${element.modelManga.source}/${element.modelManga.name}-chapter_index",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/models/model_manga.dart';
|
|||
import 'package:mangayomi/providers/hive_provider.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/views/manga/download/download_model.dart';
|
||||
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
|
||||
import 'package:mangayomi/views/widgets/bottom_text_widget.dart';
|
||||
|
|
@ -49,6 +50,7 @@ class LibraryGridViewWidget extends StatelessWidget {
|
|||
Stack(
|
||||
children: [
|
||||
cachedNetworkImage(
|
||||
headers: headers(entriesManga[index].source!),
|
||||
imageUrl: entriesManga[index].imageUrl!,
|
||||
width: 200,
|
||||
height: 270,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:mangayomi/models/model_manga.dart';
|
|||
import 'package:mangayomi/providers/hive_provider.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/media_query.dart';
|
||||
import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_provider.dart';
|
||||
import 'package:mangayomi/views/widgets/listview_widget.dart';
|
||||
|
|
@ -54,6 +55,7 @@ class LibraryListViewWidget extends StatelessWidget {
|
|||
topLeft: Radius.circular(5),
|
||||
bottomLeft: Radius.circular(5)),
|
||||
child: cachedNetworkImage(
|
||||
headers: headers(entriesManga[index].source!),
|
||||
imageUrl: entriesManga[index].imageUrl!,
|
||||
width: 40,
|
||||
height: 40,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import 'package:mangayomi/models/model_manga.dart';
|
|||
import 'package:mangayomi/providers/hive_provider.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/utils/media_query.dart';
|
||||
import 'package:mangayomi/utils/utils.dart';
|
||||
import 'package:mangayomi/views/manga/detail/providers/state_providers.dart';
|
||||
|
|
@ -226,6 +227,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
child: Stack(
|
||||
children: [
|
||||
cachedNetworkImage(
|
||||
headers: headers(widget.modelManga!.source!),
|
||||
imageUrl: widget.modelManga!.imageUrl!,
|
||||
width: mediaWidth(context, 1),
|
||||
height: 461,
|
||||
|
|
@ -510,6 +512,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
Positioned(
|
||||
top: 0,
|
||||
child: cachedNetworkImage(
|
||||
headers: headers(widget.modelManga!.source!),
|
||||
imageUrl: widget.modelManga!.imageUrl!,
|
||||
width: mediaWidth(context, 1),
|
||||
height: 300,
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ class ReverseMangaStateProvider
|
|||
}
|
||||
|
||||
String _$chapterFilterDownloadedStateHash() =>
|
||||
r'ea2313a3f81e408cdea77e98d82510e824ddd6a4';
|
||||
r'6b433670cf840fe1e8166ae5b7a4fe17c9b56b5d';
|
||||
|
||||
abstract class _$ChapterFilterDownloadedState
|
||||
extends BuildlessAutoDisposeNotifier<int> {
|
||||
|
|
@ -290,7 +290,7 @@ class ChapterFilterDownloadedStateProvider
|
|||
}
|
||||
|
||||
String _$chapterFilterUnreadStateHash() =>
|
||||
r'54a6bd0ace5db2262298ec51a7a99149aeaff047';
|
||||
r'ee96d8e6b3f145096e00ff3c09fda07d5f968047';
|
||||
|
||||
abstract class _$ChapterFilterUnreadState
|
||||
extends BuildlessAutoDisposeNotifier<int> {
|
||||
|
|
@ -389,7 +389,7 @@ class ChapterFilterUnreadStateProvider
|
|||
}
|
||||
|
||||
String _$chapterFilterBookmarkedStateHash() =>
|
||||
r'316ae7f6d11556927aa160ab950585e3e74fc8e1';
|
||||
r'f9761f9a32d0d6af53f513f862476a7125054ce7';
|
||||
|
||||
abstract class _$ChapterFilterBookmarkedState
|
||||
extends BuildlessAutoDisposeNotifier<int> {
|
||||
|
|
@ -588,7 +588,7 @@ class ChapterFilterResultStateProvider extends AutoDisposeNotifierProviderImpl<
|
|||
}
|
||||
|
||||
String _$chapterSetIsBookmarkStateHash() =>
|
||||
r'1be8afbfd3ebd0a519922f315d204d60409bed57';
|
||||
r'c12ed82216c7a649b9937226d841e413209ec704';
|
||||
|
||||
abstract class _$ChapterSetIsBookmarkState
|
||||
extends BuildlessAutoDisposeNotifier<dynamic> {
|
||||
|
|
@ -687,7 +687,7 @@ class ChapterSetIsBookmarkStateProvider extends AutoDisposeNotifierProviderImpl<
|
|||
}
|
||||
|
||||
String _$chapterSetIsReadStateHash() =>
|
||||
r'fafd4503e4e65d48f157893de2b3a2234f4b20c7';
|
||||
r'2976cee969928c8ce433e173e53ba67e6ee49d6d';
|
||||
|
||||
abstract class _$ChapterSetIsReadState
|
||||
extends BuildlessAutoDisposeNotifier<dynamic> {
|
||||
|
|
@ -786,7 +786,7 @@ class ChapterSetIsReadStateProvider
|
|||
}
|
||||
|
||||
String _$chapterSetDownloadStateHash() =>
|
||||
r'299986f635cf64cf09aafbd7da373fa3e93ac8fc';
|
||||
r'cc003f376668ea8b1c8f3f6d03190f72d172f55e';
|
||||
|
||||
abstract class _$ChapterSetDownloadState
|
||||
extends BuildlessAutoDisposeNotifier<dynamic> {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ class ChapterListTileWidget extends ConsumerWidget {
|
|||
final idx = reverse ? reverseIndex : finalIndex;
|
||||
final chapterNameList = ref.watch(chapterNameListStateProvider);
|
||||
final chapterName = modelManga.chapters![idx].name;
|
||||
log(chapterNameList.length.toString());
|
||||
return Container(
|
||||
color: chapterNameList.contains(chapterName)
|
||||
? primaryColor(context).withOpacity(0.4)
|
||||
|
|
@ -118,6 +117,22 @@ class ChapterListTileWidget extends ConsumerWidget {
|
|||
: Colors.white.withOpacity(0.3)),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (chapters[finalIndex].scanlator!.isNotEmpty)
|
||||
Row(
|
||||
children: [
|
||||
const Text(' • '),
|
||||
Text(
|
||||
chapters[finalIndex].scanlator!,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
color: chapters[finalIndex].isRead
|
||||
? isLight(context)
|
||||
? Colors.black.withOpacity(0.4)
|
||||
: Colors.white.withOpacity(0.3)
|
||||
: null),
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ 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/reg_exp_matcher.dart';
|
||||
import 'package:mangayomi/views/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
|
||||
class ImageViewVertical extends StatelessWidget {
|
||||
class ImageViewVertical extends StatefulWidget {
|
||||
final int length;
|
||||
final bool isLocale;
|
||||
final String url;
|
||||
|
|
@ -29,25 +30,33 @@ class ImageViewVertical extends StatelessWidget {
|
|||
required this.isLocale,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ImageViewVertical> createState() => _ImageViewVerticalState();
|
||||
}
|
||||
|
||||
class _ImageViewVerticalState extends State<ImageViewVertical>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Container(
|
||||
color: Colors.black,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (index == 0)
|
||||
if (widget.index == 0)
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).padding.top,
|
||||
),
|
||||
isLocale
|
||||
widget.isLocale
|
||||
? ExtendedImage.file(
|
||||
fit: BoxFit.contain,
|
||||
clearMemoryCacheWhenDispose: true,
|
||||
enableMemoryCache: false,
|
||||
File('${path.path}${padIndex(index + 1)}.jpg'))
|
||||
File('${widget.path.path}${padIndex(widget.index + 1)}.jpg'))
|
||||
: ExtendedImage(
|
||||
image: FastCachedImageProvider(url, headers: headers(source)),
|
||||
image: FastCachedImageProvider(widget.url,
|
||||
headers: headers(widget.source)),
|
||||
handleLoadingProgress: true,
|
||||
fit: BoxFit.contain,
|
||||
clearMemoryCacheWhenDispose: true,
|
||||
|
|
@ -61,24 +70,11 @@ class ImageViewVertical extends StatelessWidget {
|
|||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return TweenAnimationBuilder<double>(
|
||||
duration: const Duration(milliseconds: 900),
|
||||
curve: Curves.elasticIn,
|
||||
tween: Tween<double>(
|
||||
begin: 0,
|
||||
end: progress,
|
||||
),
|
||||
builder: (context, value, _) => Container(
|
||||
color: Colors.black,
|
||||
height: mediaHeight(context, 0.8),
|
||||
child: Center(
|
||||
child: progress == 0
|
||||
? const CircularProgressIndicator()
|
||||
: CircularProgressIndicator(
|
||||
value: progress,
|
||||
),
|
||||
),
|
||||
),
|
||||
return Container(
|
||||
color: Colors.black,
|
||||
height: mediaHeight(context, 0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState == LoadState.failed) {
|
||||
|
|
@ -101,14 +97,14 @@ class ImageViewVertical extends StatelessWidget {
|
|||
}
|
||||
return null;
|
||||
}),
|
||||
if (index + 1 == length)
|
||||
if (widget.index + 1 == widget.length)
|
||||
SizedBox(
|
||||
height: mediaHeight(context, 0.3),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'$chapter finished',
|
||||
'${widget.chapter} finished',
|
||||
style: const TextStyle(
|
||||
fontSize: 17.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
@ -131,4 +127,7 @@ class ImageViewVertical extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import 'package:mangayomi/utils/media_query.dart';
|
|||
import 'package:mangayomi/views/manga/reader/image_view_horizontal.dart';
|
||||
import 'package:mangayomi/views/manga/reader/image_view_vertical.dart';
|
||||
import 'package:mangayomi/views/manga/reader/providers/reader_controller_provider.dart';
|
||||
import 'package:mangayomi/views/manga/reader/widgets/circular_progress_indicator_animate_rotate.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:photo_view/photo_view_gallery.dart';
|
||||
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
|
||||
|
|
@ -41,11 +42,15 @@ class MangaReaderView extends ConsumerWidget {
|
|||
readerControllerProvider(mangaReaderModel: mangaReaderModel).notifier);
|
||||
return chapterData.when(
|
||||
data: (data) {
|
||||
if (data.urll.isEmpty) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
return MangaChapterPageGallery(
|
||||
path: data.path!,
|
||||
url: data.urll,
|
||||
readerController: readerController,
|
||||
isLocaleList: data.isLocaleList,
|
||||
mangaReaderModel: mangaReaderModel,
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => Scaffold(
|
||||
|
|
@ -106,11 +111,13 @@ class MangaChapterPageGallery extends ConsumerStatefulWidget {
|
|||
required this.path,
|
||||
required this.url,
|
||||
required this.readerController,
|
||||
required this.isLocaleList});
|
||||
required this.isLocaleList,
|
||||
required this.mangaReaderModel});
|
||||
final ReaderController readerController;
|
||||
final Directory path;
|
||||
final List url;
|
||||
final List<bool> isLocaleList;
|
||||
final MangaReaderModel mangaReaderModel;
|
||||
|
||||
@override
|
||||
ConsumerState createState() {
|
||||
|
|
@ -129,12 +136,13 @@ class _MangaChapterPageGalleryState
|
|||
late bool _isBookmarked = widget.readerController.getChapterBookmarked();
|
||||
@override
|
||||
void dispose() {
|
||||
_rebuildDetail.close();
|
||||
_doubleClickAnimationController.dispose();
|
||||
clearGestureDetailsCache();
|
||||
widget.readerController.setMangaHistoryUpdate();
|
||||
widget.readerController.setPageIndex(_currentIndex);
|
||||
widget.readerController.setChapterPageLastRead(_currentIndex);
|
||||
_rebuildDetail.close();
|
||||
_doubleClickAnimationController.dispose();
|
||||
clearGestureDetailsCache();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +170,9 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
|
||||
void _onPageChanged(int index) {
|
||||
ref.read(currentIndexProvider.notifier).setCurrentIndex(index);
|
||||
ref
|
||||
.read(currentIndexProvider(widget.mangaReaderModel).notifier)
|
||||
.setCurrentIndex(index);
|
||||
_currentIndex = index;
|
||||
|
||||
if (_imageDetailY != 0) {
|
||||
|
|
@ -248,7 +258,9 @@ class _MangaChapterPageGalleryState
|
|||
}
|
||||
|
||||
void _recordReadProgress(int index) {
|
||||
ref.read(currentIndexProvider.notifier).setCurrentIndex(index);
|
||||
ref
|
||||
.read(currentIndexProvider(widget.mangaReaderModel).notifier)
|
||||
.setCurrentIndex(index);
|
||||
_currentIndex = index;
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +375,8 @@ class _MangaChapterPageGalleryState
|
|||
Widget _showMore() {
|
||||
return Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final currentIndex = ref.watch(currentIndexProvider);
|
||||
final currentIndex =
|
||||
ref.watch(currentIndexProvider(widget.mangaReaderModel));
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
|
|
@ -661,7 +674,8 @@ class _MangaChapterPageGalleryState
|
|||
Widget _showPage() {
|
||||
return Consumer(
|
||||
builder: (context, ref, child) {
|
||||
final currentIndex = ref.watch(currentIndexProvider);
|
||||
final currentIndex =
|
||||
ref.watch(currentIndexProvider(widget.mangaReaderModel));
|
||||
return _isView
|
||||
? Container()
|
||||
: _showPagesNumber
|
||||
|
|
@ -924,24 +938,11 @@ class _MangaChapterPageGalleryState
|
|||
? loadingProgress!.cumulativeBytesLoaded /
|
||||
loadingProgress.expectedTotalBytes!
|
||||
: 0;
|
||||
return TweenAnimationBuilder<double>(
|
||||
duration: const Duration(seconds: 900),
|
||||
curve: Curves.elasticIn,
|
||||
tween: Tween<double>(
|
||||
begin: 0,
|
||||
end: progress,
|
||||
),
|
||||
builder: (context, value, _) => Container(
|
||||
color: Colors.black,
|
||||
height: mediaHeight(context, 0.8),
|
||||
child: Center(
|
||||
child: progress == 0
|
||||
? const CircularProgressIndicator()
|
||||
: CircularProgressIndicator(
|
||||
value: progress,
|
||||
),
|
||||
),
|
||||
),
|
||||
return Container(
|
||||
color: Colors.black,
|
||||
height: mediaHeight(context, 0.8),
|
||||
child: CircularProgressIndicatorAnimateRotate(
|
||||
progress: progress),
|
||||
);
|
||||
}
|
||||
if (state.extendedImageLoadState ==
|
||||
|
|
|
|||
|
|
@ -24,7 +24,14 @@ enum ReaderMode {
|
|||
@riverpod
|
||||
class CurrentIndex extends _$CurrentIndex {
|
||||
@override
|
||||
int build() {
|
||||
int build(MangaReaderModel mangaReaderModel) {
|
||||
final incognitoMode = ref.watch(incognitoModeStateProvider);
|
||||
if (!incognitoMode) {
|
||||
return ref
|
||||
.read(readerControllerProvider(mangaReaderModel: mangaReaderModel)
|
||||
.notifier)
|
||||
.getPageIndex();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,22 +64,7 @@ class ReaderModeAdapter extends TypeAdapter<ReaderMode> {
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$currentIndexHash() => r'af7ea51b2aa8a5c6db401c52958879b87fc56973';
|
||||
|
||||
/// See also [CurrentIndex].
|
||||
@ProviderFor(CurrentIndex)
|
||||
final currentIndexProvider =
|
||||
AutoDisposeNotifierProvider<CurrentIndex, int>.internal(
|
||||
CurrentIndex.new,
|
||||
name: r'currentIndexProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product') ? null : _$currentIndexHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$CurrentIndex = AutoDisposeNotifier<int>;
|
||||
String _$readerControllerHash() => r'a389f9b08001c6863a651f6c2ed3d1b18588d5b0';
|
||||
String _$currentIndexHash() => r'13515f4fe649912e0a0cade86c968152481b56f2';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -102,6 +87,103 @@ class _SystemHash {
|
|||
}
|
||||
}
|
||||
|
||||
abstract class _$CurrentIndex extends BuildlessAutoDisposeNotifier<int> {
|
||||
late final MangaReaderModel mangaReaderModel;
|
||||
|
||||
int build(
|
||||
MangaReaderModel mangaReaderModel,
|
||||
);
|
||||
}
|
||||
|
||||
/// See also [CurrentIndex].
|
||||
@ProviderFor(CurrentIndex)
|
||||
const currentIndexProvider = CurrentIndexFamily();
|
||||
|
||||
/// See also [CurrentIndex].
|
||||
class CurrentIndexFamily extends Family<int> {
|
||||
/// See also [CurrentIndex].
|
||||
const CurrentIndexFamily();
|
||||
|
||||
/// See also [CurrentIndex].
|
||||
CurrentIndexProvider call(
|
||||
MangaReaderModel mangaReaderModel,
|
||||
) {
|
||||
return CurrentIndexProvider(
|
||||
mangaReaderModel,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
CurrentIndexProvider getProviderOverride(
|
||||
covariant CurrentIndexProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.mangaReaderModel,
|
||||
);
|
||||
}
|
||||
|
||||
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'currentIndexProvider';
|
||||
}
|
||||
|
||||
/// See also [CurrentIndex].
|
||||
class CurrentIndexProvider
|
||||
extends AutoDisposeNotifierProviderImpl<CurrentIndex, int> {
|
||||
/// See also [CurrentIndex].
|
||||
CurrentIndexProvider(
|
||||
this.mangaReaderModel,
|
||||
) : super.internal(
|
||||
() => CurrentIndex()..mangaReaderModel = mangaReaderModel,
|
||||
from: currentIndexProvider,
|
||||
name: r'currentIndexProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$currentIndexHash,
|
||||
dependencies: CurrentIndexFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
CurrentIndexFamily._allTransitiveDependencies,
|
||||
);
|
||||
|
||||
final MangaReaderModel mangaReaderModel;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is CurrentIndexProvider &&
|
||||
other.mangaReaderModel == mangaReaderModel;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, mangaReaderModel.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
||||
@override
|
||||
int runNotifierBuild(
|
||||
covariant CurrentIndex notifier,
|
||||
) {
|
||||
return notifier.build(
|
||||
mangaReaderModel,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
String _$readerControllerHash() => r'8999132e4d6b64b2c652d641cbef9ae6e9175d0e';
|
||||
|
||||
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
|
||||
late final MangaReaderModel mangaReaderModel;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CircularProgressIndicatorAnimateRotate extends StatefulWidget {
|
||||
final double progress;
|
||||
const CircularProgressIndicatorAnimateRotate(
|
||||
{Key? key, required this.progress})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<CircularProgressIndicatorAnimateRotate> createState() =>
|
||||
_CircularProgressIndicatorAnimateRotateState();
|
||||
}
|
||||
|
||||
class _CircularProgressIndicatorAnimateRotateState
|
||||
extends State<CircularProgressIndicatorAnimateRotate>
|
||||
with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller =
|
||||
AnimationController(vsync: this, duration: const Duration(seconds: 10))
|
||||
..repeat();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: widget.progress == 0
|
||||
? const CircularProgressIndicator()
|
||||
: AnimatedBuilder(
|
||||
animation: _controller,
|
||||
builder: (_, child) {
|
||||
return Transform.rotate(
|
||||
angle: _controller.value * 2 * pi,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
child: TweenAnimationBuilder<double>(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
curve: Curves.easeInOut,
|
||||
tween: Tween<double>(
|
||||
begin: 0,
|
||||
end: widget.progress,
|
||||
),
|
||||
builder: (context, value, _) => CircularProgressIndicator(
|
||||
value: value,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue