*chapter filter

This commit is contained in:
kodjodevf 2023-04-19 18:00:21 +01:00
parent 7c345bf00b
commit 92d7ad30e7
29 changed files with 716 additions and 341 deletions

View file

@ -29,6 +29,7 @@ void main() async {
Hive.registerAdapter(ReaderModeAdapter());
Hive.registerAdapter(TypeSourceAdapter());
Hive.registerAdapter(DownloadModelAdapter());
Hive.registerAdapter(ModelChaptersAdapter());
await Hive.openBox<ModelManga>(HiveConstant.hiveBoxManga);
await Hive.openBox<MangaHistoryModel>(HiveConstant.hiveBoxMangaHistory);
await Hive.openBox<ReaderMode>(HiveConstant.hiveBoxReaderMode);

View file

@ -29,31 +29,28 @@ class ModelManga extends HiveObject {
bool favorite;
@HiveField(8)
List<String>? chapterTitle;
@HiveField(9)
List<String>? chapterUrl;
@HiveField(10)
List<String>? chapterDate;
@HiveField(11)
String? source;
@HiveField(12)
@HiveField(9)
String? lang;
@HiveField(13)
@HiveField(10)
int? dateAdded;
@HiveField(14)
@HiveField(11)
int? lastUpdate;
@HiveField(12)
List<ModelChapters>? chapters;
@HiveField(13)
String? lastRead;
@HiveField(14)
int? category;
ModelManga(
{required this.chapterDate,
required this.source,
required this.chapterTitle,
required this.chapterUrl,
{required this.source,
required this.author,
required this.favorite,
required this.genre,
@ -64,5 +61,41 @@ class ModelManga extends HiveObject {
required this.status,
required this.description,
required this.dateAdded,
required this.lastUpdate});
required this.lastUpdate,
required this.category,
required this.lastRead,
required this.chapters});
}
@HiveType(typeId: 7)
class ModelChapters extends HiveObject {
@HiveField(0)
String? name;
@HiveField(1)
String? url;
@HiveField(2)
String? dateUpload;
@HiveField(3)
String? scanlator;
@HiveField(4)
bool isBookmarked;
@HiveField(5)
bool isRead;
@HiveField(6)
String lastPageRead;
ModelChapters(
{required this.name,
required this.url,
required this.dateUpload,
required this.isBookmarked,
required this.scanlator,
required this.isRead,
required this.lastPageRead});
}

View file

@ -17,21 +17,21 @@ class ModelMangaAdapter extends TypeAdapter<ModelManga> {
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return ModelManga(
chapterDate: (fields[10] as List?)?.cast<String>(),
source: fields[11] as String?,
chapterTitle: (fields[8] as List?)?.cast<String>(),
chapterUrl: (fields[9] as List?)?.cast<String>(),
source: fields[8] as String?,
author: fields[4] as String?,
favorite: fields[7] as bool,
genre: (fields[6] as List?)?.cast<String>(),
imageUrl: fields[2] as String?,
lang: fields[12] as String?,
lang: fields[9] as String?,
link: fields[1] as String?,
name: fields[0] as String?,
status: fields[5] as String?,
description: fields[3] as String?,
dateAdded: fields[13] as int?,
lastUpdate: fields[14] as int?,
dateAdded: fields[10] as int?,
lastUpdate: fields[11] as int?,
category: fields[14] as int?,
lastRead: fields[13] as String?,
chapters: (fields[12] as List?)?.cast<ModelChapters>(),
);
}
@ -56,19 +56,19 @@ class ModelMangaAdapter extends TypeAdapter<ModelManga> {
..writeByte(7)
..write(obj.favorite)
..writeByte(8)
..write(obj.chapterTitle)
..writeByte(9)
..write(obj.chapterUrl)
..writeByte(10)
..write(obj.chapterDate)
..writeByte(11)
..write(obj.source)
..writeByte(12)
..writeByte(9)
..write(obj.lang)
..writeByte(13)
..writeByte(10)
..write(obj.dateAdded)
..writeByte(11)
..write(obj.lastUpdate)
..writeByte(12)
..write(obj.chapters)
..writeByte(13)
..write(obj.lastRead)
..writeByte(14)
..write(obj.lastUpdate);
..write(obj.category);
}
@override
@ -81,3 +81,55 @@ class ModelMangaAdapter extends TypeAdapter<ModelManga> {
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class ModelChaptersAdapter extends TypeAdapter<ModelChapters> {
@override
final int typeId = 7;
@override
ModelChapters read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return ModelChapters(
name: fields[0] as String?,
url: fields[1] as String?,
dateUpload: fields[2] as String?,
isBookmarked: fields[4] as bool,
scanlator: fields[3] as String?,
isRead: fields[5] as bool,
lastPageRead: fields[6] as String,
);
}
@override
void write(BinaryWriter writer, ModelChapters obj) {
writer
..writeByte(7)
..writeByte(0)
..write(obj.name)
..writeByte(1)
..write(obj.url)
..writeByte(2)
..write(obj.dateUpload)
..writeByte(3)
..write(obj.scanlator)
..writeByte(4)
..write(obj.isBookmarked)
..writeByte(5)
..write(obj.isRead)
..writeByte(6)
..write(obj.lastPageRead);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ModelChaptersAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View file

@ -38,7 +38,7 @@ class StorageProvider {
ModelManga modelManga, index) async {
final dir = await getDirectory();
return Directory(
"${dir!.path}/downloads/${modelManga.source} (${modelManga.lang!.toUpperCase()})/${modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${modelManga.chapterTitle![index].replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/");
"${dir!.path}/downloads/${modelManga.source} (${modelManga.lang!.toUpperCase()})/${modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${modelManga.chapters![index].name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/");
}
Future<Directory?> getMangaMainDirectory(ModelManga modelManga, index) async {

View file

@ -1,7 +1,6 @@
// ignore_for_file: depend_on_referenced_packages
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:html/dom.dart' as dom;
@ -32,14 +31,14 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
Directory? path;
List urll = [];
String source = modelManga.source!.toLowerCase();
List hiveUrl = ref.watch(hiveBoxMangaInfo).get(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
List pagesUrl = ref.watch(hiveBoxMangaInfo).get(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
defaultValue: []);
final incognitoMode = ref.watch(incognitoModeStateProvider);
path = await StorageProvider().getMangaChapterDirectory(modelManga, index);
if (hiveUrl.isNotEmpty) {
urll = hiveUrl;
if (pagesUrl.isNotEmpty) {
urll = pagesUrl;
}
/*********/
@ -47,7 +46,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
/********/
else if (getWpMangTypeSource(source) == TypeSource.comick) {
String mangaId =
modelManga.chapterUrl![index].split('/').last.split('-').first;
modelManga.chapters![index].url!.split('/').last.split('-').first;
var headers = {
'Referer': 'https://comick.app/',
'User-Agent':
@ -68,7 +67,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
}
if (!incognitoMode) {
ref.watch(hiveBoxMangaInfo).put(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
urll);
}
}
@ -78,7 +77,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
else if (getWpMangTypeSource(source) == TypeSource.mangathemesia) {
final htmll =
await httpResToDom(url: modelManga.chapterUrl![index], headers: {});
await httpResToDom(url: modelManga.chapters![index].url!, headers: {});
if (htmll.querySelectorAll('#readerarea').isNotEmpty) {
final ta = htmll
@ -120,7 +119,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
}
if (!incognitoMode) {
ref.watch(hiveBoxMangaInfo).put(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
urll);
}
}
@ -131,7 +130,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
/***********/
else if (modelManga.source == 'mangakawaii') {
final response = await http.get(Uri.parse(modelManga.chapterUrl![index]));
final response = await http.get(Uri.parse(modelManga.chapters![index].url!));
var chapterSlug = RegExp("""var chapter_slug = "([^"]*)";""")
.allMatches(response.body.toString())
.last
@ -150,7 +149,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
}
if (!incognitoMode) {
ref.watch(hiveBoxMangaInfo).put(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
urll);
}
}
@ -161,7 +160,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
else if (getWpMangTypeSource(source) == TypeSource.mmrcms) {
final dom =
await httpResToDom(url: modelManga.chapterUrl![index], headers: {});
await httpResToDom(url: modelManga.chapters![index].url!, headers: {});
if (dom.querySelectorAll('#all > .img-responsive').isNotEmpty) {
urll = dom.querySelectorAll('#all > .img-responsive').map((e) {
@ -184,7 +183,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
// log(message)
if (!incognitoMode) {
ref.watch(hiveBoxMangaInfo).put(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
urll);
}
}
@ -216,12 +215,12 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
}
final response = await http.get(
Uri.parse("http://www.mangahere.cc${modelManga.chapterUrl![index]}"),
Uri.parse("http://www.mangahere.cc${modelManga.chapters![index].url!}"),
headers: {
"Referer": "https://www.mangahere.cc/",
"Cookie": "isAdult=1"
});
var link = "http://www.mangahere.cc${modelManga.chapterUrl![index]}";
var link = "http://www.mangahere.cc${modelManga.chapters![index].url!}";
dom.Document htmll = dom.Document.html(response.body);
int? pagesNumber = -1;
if (htmll.querySelectorAll('body > div > div > span > a:').isNotEmpty) {
@ -303,7 +302,7 @@ Future<GetMangaChapterUrlModel> getMangaChapterUrl(
flutterJs.dispose();
if (!incognitoMode) {
ref.watch(hiveBoxMangaInfo).put(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![index]}-pageurl",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![index].name}-pageurl",
urll);
}
}

View file

@ -7,7 +7,7 @@ part of 'get_manga_chapter_url.dart';
// **************************************************************************
String _$getMangaChapterUrlHash() =>
r'3a7026ca88efc6cedff804e23d0f04224d6d88d8';
r'dda553ecccf269ea375550eba379f57b8ede0263';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -3,6 +3,7 @@ import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:mangayomi/models/comick/manga_chapter_detail.dart';
import 'package:mangayomi/models/comick/manga_detail_comick.dart';
import 'package:mangayomi/models/model_manga.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';
@ -12,9 +13,7 @@ part 'get_manga_detail.g.dart';
class GetMangaDetailModel {
List<String> genre = [];
List<String> chapterTitle = [];
List<String> chapterUrl = [];
List<String> chapterDate = [];
List<ModelChapters> chapters = [];
String? author;
String? status;
String? source;
@ -26,9 +25,7 @@ class GetMangaDetailModel {
required this.genre,
required this.author,
required this.status,
required this.chapterDate,
required this.chapterTitle,
required this.chapterUrl,
required this.chapters,
required this.imageUrl,
required this.description,
required this.url,
@ -89,7 +86,7 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
List<String> chapterUrl = [];
List<String> chapterDate = [];
String? description;
List<ModelChapters> chapters = [];
/********/
/*comick*/
/********/
@ -594,11 +591,22 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
}
}
}
if (chapterDate.isNotEmpty &&
chapterTitle.isNotEmpty &&
chapterUrl.isNotEmpty) {
for (var i = 0; i < chapterUrl.length; i++) {
chapters.add(ModelChapters(
name: chapterTitle[i],
url: chapterUrl[i],
dateUpload: chapterDate[i],
isBookmarked: false,
scanlator: "",
isRead: false,
lastPageRead: ''));
}
}
return GetMangaDetailModel(
chapterDate: chapterDate,
chapterTitle: chapterTitle,
chapterUrl: chapterUrl,
status: status,
genre: genre,
author: author,
@ -607,5 +615,6 @@ Future<GetMangaDetailModel> getMangaDetail(GetMangaDetailRef ref,
url: url,
source: source,
imageUrl: imageUrl,
chapters: chapters,
);
}

View file

@ -6,7 +6,7 @@ part of 'get_manga_detail.dart';
// RiverpodGenerator
// **************************************************************************
String _$getMangaDetailHash() => r'0beaacd9a8611bd3763bf3f92ea71b2eb133d40c';
String _$getMangaDetailHash() => r'60fe1b4618a6b6e2b9479999974a47b91f4a8568';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
generalColor(BuildContext context) {
return Theme.of(context).toggleButtonsTheme.color;
Color generalColor(BuildContext context) {
return Theme.of(context).toggleButtonsTheme.color!;
}
secondaryColor(BuildContext context) {
Color secondaryColor(BuildContext context) {
return Theme.of(context).iconTheme.color!.withOpacity(0.7);
}

5
lib/utils/utils.dart Normal file
View file

@ -0,0 +1,5 @@
import 'package:flutter/material.dart';
bool isLight(BuildContext context) {
return Theme.of(context).brightness == Brightness.light;
}

View file

@ -185,9 +185,6 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
name: data.name,
genre: data.genre,
author: data.author,
chapterDate: data.chapterDate,
chapterTitle: data.chapterTitle,
chapterUrl: data.chapterUrl,
status: data.status,
description: data.description,
favorite: false,
@ -195,7 +192,10 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
source: data.source,
lang: widget.lang,
dateAdded: DateTime.now().microsecondsSinceEpoch,
lastUpdate: DateTime.now().microsecondsSinceEpoch);
lastUpdate: DateTime.now().microsecondsSinceEpoch,
chapters: data.chapters,
category: null,
lastRead: '');
if (mounted) {
context.push('/manga-reader/detail', extra: modelManga);
}

View file

@ -199,10 +199,12 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen> {
MainAxisAlignment.start,
children: [
Text(
element.modelManga
.chapterTitle![
int.parse(values
.toString())],
element
.modelManga
.chapters![int.parse(
values
.toString())]
.name!,
style: const TextStyle(
fontSize: 11,
),

View file

@ -24,6 +24,35 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
List<ModelManga> entries = [];
List<ModelManga> entriesFilter = [];
final _textEditingController = TextEditingController();
List<ModelManga> bookmark() {
List<ModelManga> mang = [];
for (var entry in entries) {
final d = entry.chapters!.where((element) => element.isBookmarked == true);
List<ModelChapters> chap = [];
for (var a in d) {
chap.add(a);
}
mang.add(ModelManga(
source: entry.source,
author: entry.author,
favorite: entry.favorite,
genre: entry.genre,
imageUrl: entry.imageUrl,
lang: entry.lang,
link: entry.link,
name: entry.name,
status: entry.status,
description: entry.description,
dateAdded: entry.dateAdded,
lastUpdate: entry.lastUpdate,
category: entry.category,
lastRead: entry.lastRead,
chapters: chap));
}
return mang;
}
@override
Widget build(BuildContext context) {
final reverse = ref.watch(libraryReverseListStateProvider);
@ -99,6 +128,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
: reverse
? entries.reversed.toList()
: entries;
if (entries.isNotEmpty || entriesFilter.isNotEmpty) {
return displayType == DisplayType.list
? LibraryListViewWidget(

View file

@ -54,10 +54,7 @@ class LibraryGridViewWidget extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(1),
child: Text(
entriesManga[index]
.chapterDate!
.length
.toString(),
entriesManga[index].chapters!.length.toString(),
style: const TextStyle(color: Colors.white),
),
),

View file

@ -56,7 +56,7 @@ class LibraryListViewWidget extends StatelessWidget {
child: Padding(
padding: const EdgeInsets.all(1),
child: Text(
entriesManga[index].chapterDate!.length.toString(),
entriesManga[index].chapters!.length.toString(),
style: const TextStyle(color: Colors.white),
),
),

View file

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:draggable_scrollbar/draggable_scrollbar.dart';
import 'package:flutter/material.dart';
@ -5,12 +7,17 @@ import 'package:flutter/rendering.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/models/manga_reader.dart';
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/media_query.dart';
import 'package:mangayomi/utils/utils.dart';
import 'package:mangayomi/views/manga/detail/manga_details_view.dart';
import 'package:mangayomi/views/manga/detail/providers/state_providers.dart';
import 'package:mangayomi/views/manga/detail/readmore.dart';
import 'package:mangayomi/views/manga/detail/widgets/chapter_listtile_widget.dart';
import 'package:mangayomi/views/manga/download/download_page_widget.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
class MangaDetailView extends ConsumerStatefulWidget {
final Function(bool) isExtended;
@ -51,6 +58,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
ScrollController _scrollController = ScrollController();
@override
Widget build(BuildContext context) {
final isLongPressed = ref.watch(isLongPressedProvider);
return NotificationListener<UserScrollNotification>(
onNotification: (notification) {
if (notification.direction == ScrollDirection.forward) {
@ -67,36 +75,50 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
preferredSize: Size.fromHeight(AppBar().preferredSize.height),
child: Consumer(
builder: (context, ref, child) {
final isLongPressed = ref.watch(isLongPressedProvider);
final reverse = ref.watch(reverseMangaStateProvider);
return AppBar(
title: ref.watch(offetProvider) > 200
? Text(
widget.modelManga!.name!,
style: const TextStyle(fontSize: 17),
)
: null,
backgroundColor: ref.watch(offetProvider) == 0.0
? Colors.transparent
: Theme.of(context).scaffoldBackgroundColor,
actions: [
// IconButton(
// splashRadius: 20,
// onPressed: () {},
// icon: Icon(Icons.download_outlined,
// color: Theme.of(context).hintColor)),
IconButton(
splashRadius: 20,
onPressed: () {
ref.read(reverseMangaStateProvider.notifier).state =
!reverse;
},
icon: Icon(
reverse
? Icons.arrow_downward_sharp
: Icons.arrow_upward_sharp,
color: Theme.of(context).hintColor)),
],
);
return isLongPressed
? AppBar(
backgroundColor: generalColor(context),
leading: IconButton(
onPressed: () {
ref.read(chapterIndexProvider.notifier).state =
-1;
ref.read(isLongPressedProvider.notifier).state =
!isLongPressed;
},
icon: const Icon(Icons.clear)),
)
: AppBar(
title: ref.watch(offetProvider) > 200
? Text(
widget.modelManga!.name!,
style: const TextStyle(fontSize: 17),
)
: null,
backgroundColor: ref.watch(offetProvider) == 0.0
? Colors.transparent
: Theme.of(context).scaffoldBackgroundColor,
actions: [
// IconButton(
// splashRadius: 20,
// onPressed: () {},
// icon: Icon(Icons.download_outlined,
// color: Theme.of(context).hintColor)),
IconButton(
splashRadius: 20,
onPressed: () {
ref
.read(reverseMangaStateProvider.notifier)
.state = !reverse;
},
icon: Icon(
reverse
? Icons.arrow_downward_sharp
: Icons.arrow_upward_sharp,
color: Theme.of(context).hintColor)),
],
);
},
)),
body: Stack(
@ -125,81 +147,184 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
)
],
)),
SafeArea(child: _listView()),
SafeArea(child: Consumer(builder: (context, ref, child) {
final reverse = ref.watch(reverseMangaStateProvider);
return DraggableScrollbar(
heightScrollThumb: 48.0,
backgroundColor: generalColor(context),
scrollThumbBuilder: (backgroundColor, thumbAnimation,
labelAnimation, height,
{labelConstraints, labelText}) {
return FadeTransition(
opacity: thumbAnimation,
child: Container(
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20)),
height: height,
width: 10.0,
),
);
},
scrollbarTimeToFade: const Duration(seconds: 2),
controller: _scrollController,
child: ListView.builder(
controller: _scrollController,
padding: const EdgeInsets.only(top: 0),
itemCount: widget.listLength,
itemBuilder: (context, index) {
int finalIndex = index - 1;
if (index == 0) {
return _bodyContainer();
}
int reverseIndex = widget
.modelManga!.chapters!.length -
widget.modelManga!.chapters!.reversed
.toList()
.indexOf(widget.modelManga!.chapters!.reversed
.toList()[finalIndex]) -
1;
List<ModelChapters> chapters = reverse
? widget.modelManga!.chapters!.reversed.toList()
: widget.modelManga!.chapters!;
return ChapterListTileWidget(
chapters: chapters,
modelManga: widget.modelManga!,
reverse: reverse,
reverseIndex: reverseIndex,
finalIndex: finalIndex,
isLongPressed: isLongPressed);
}));
})),
],
),
));
}
Widget _listView() {
return Consumer(builder: (context, ref, child) {
final reverse = ref.watch(reverseMangaStateProvider);
return DraggableScrollbar(
heightScrollThumb: 48.0,
backgroundColor: generalColor(context),
scrollThumbBuilder:
(backgroundColor, thumbAnimation, labelAnimation, height,
{labelConstraints, labelText}) {
return FadeTransition(
opacity: thumbAnimation,
child: Container(
bottomNavigationBar: Consumer(
builder: (context, ref, child) {
final idx = ref.watch(chapterIndexProvider);
final chapter = ref.watch(chapterModelProvider);
return AnimatedContainer(
curve: Curves.easeIn,
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(20)),
height: height,
width: 10.0,
),
);
},
scrollbarTimeToFade: const Duration(seconds: 2),
controller: _scrollController,
child: ListView.builder(
controller: _scrollController,
padding: const EdgeInsets.only(top: 0),
itemCount: widget.listLength,
itemBuilder: (context, index) {
int finalIndex = index - 1;
if (index == 0) {
return _bodyContainer();
}
color: generalColor(context).withOpacity(0.3),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20))),
duration: const Duration(milliseconds: 100),
height: isLongPressed ? 70 : 0,
width: mediaWidth(context, 1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
IconButton(
onPressed: () async {
List<ModelChapters> chap = [];
for (var i = 0;
i < widget.modelManga!.chapters!.length;
i++) {
chap.add(ModelChapters(
name: widget.modelManga!.chapters![i].name,
url: widget.modelManga!.chapters![i].url,
dateUpload:
widget.modelManga!.chapters![i].dateUpload,
isBookmarked: idx == i
? widget.modelManga!.chapters![i].isBookmarked
? false
: true
: widget
.modelManga!.chapters![i].isBookmarked,
scanlator:
widget.modelManga!.chapters![i].scanlator,
isRead: widget.modelManga!.chapters![i].isRead,
lastPageRead: widget
.modelManga!.chapters![i].lastPageRead));
}
int reverseIndex = widget.modelManga!.chapterDate!.length -
widget.modelManga!.chapterDate!.reversed.toList().indexOf(
widget.modelManga!.chapterDate!.reversed
.toList()[finalIndex]) -
1;
List<String>? chapterUrl = reverse
? widget.modelManga!.chapterUrl!.reversed.toList()
: widget.modelManga!.chapterUrl!;
List<String>? chapterDate = reverse
? widget.modelManga!.chapterDate!.reversed.toList()
: widget.modelManga!.chapterDate!;
List<String>? chapterTitle = reverse
? widget.modelManga!.chapterTitle!.reversed.toList()
: widget.modelManga!.chapterTitle!;
// print(idx);
final model = ModelManga(
imageUrl: widget.modelManga!.imageUrl,
name: widget.modelManga!.name,
genre: widget.modelManga!.genre,
author: widget.modelManga!.author,
description: widget.modelManga!.description,
status: widget.modelManga!.status,
favorite: widget.modelManga!.favorite,
link: widget.modelManga!.link,
source: widget.modelManga!.source,
lang: widget.modelManga!.lang,
dateAdded: widget.modelManga!.dateAdded,
lastUpdate: widget.modelManga!.lastUpdate,
chapters: chap,
category: widget.modelManga!.category,
lastRead: widget.modelManga!.lastRead);
ref.watch(hiveBoxManga).put(
'${widget.modelManga!.lang}-${widget.modelManga!.link}',
model);
ref.read(chapterModelProvider.notifier).state =
chap[idx];
},
icon: Icon(chapter.isBookmarked
? Icons.bookmark_remove
: Icons.bookmark_add_outlined)),
IconButton(
onPressed: () {
List<ModelChapters> chap = [];
for (var i = 0;
i < widget.modelManga!.chapters!.length;
i++) {
chap.add(ModelChapters(
name: widget.modelManga!.chapters![i].name,
url: widget.modelManga!.chapters![i].url,
dateUpload:
widget.modelManga!.chapters![i].dateUpload,
isBookmarked:
widget.modelManga!.chapters![i].isBookmarked,
scanlator:
widget.modelManga!.chapters![i].scanlator,
isRead: idx == i
? widget.modelManga!.chapters![i].isRead
? false
: true
: widget.modelManga!.chapters![i].isRead,
lastPageRead: widget
.modelManga!.chapters![i].lastPageRead));
}
return ListTile(
key: ObjectKey(chapterUrl),
onTap: () {
pushMangaReaderView(
context: context,
modelManga: widget.modelManga!,
index: reverse ? reverseIndex : finalIndex);
},
trailing: ref.watch(ChapterPageDownloadsProvider(
index: reverse ? reverseIndex : finalIndex,
modelManga: widget.modelManga!)),
subtitle: Text(
chapterDate[finalIndex],
style: const TextStyle(fontSize: 11),
),
title: Text(
chapterTitle[finalIndex],
style: const TextStyle(fontSize: 13),
),
);
}));
});
final model = ModelManga(
imageUrl: widget.modelManga!.imageUrl,
name: widget.modelManga!.name,
genre: widget.modelManga!.genre,
author: widget.modelManga!.author,
description: widget.modelManga!.description,
status: widget.modelManga!.status,
favorite: widget.modelManga!.favorite,
link: widget.modelManga!.link,
source: widget.modelManga!.source,
lang: widget.modelManga!.lang,
dateAdded: widget.modelManga!.dateAdded,
lastUpdate: widget.modelManga!.lastUpdate,
chapters: chap,
category: widget.modelManga!.category,
lastRead: widget.modelManga!.lastRead);
ref.watch(hiveBoxManga).put(
'${widget.modelManga!.lang}-${widget.modelManga!.link}',
model);
ref.read(chapterModelProvider.notifier).state =
chap[idx];
},
icon: Icon(chapter.isRead
? Icons.remove_done_sharp
: Icons.done_all_sharp)),
IconButton(
onPressed: () {}, icon: const Icon(Icons.download))
],
),
);
},
),
));
}
Widget _bodyContainer() {
@ -271,6 +396,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
height: 30,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
backgroundColor:
Colors.grey.withOpacity(0.2),
shape: RoundedRectangleBorder(
@ -279,9 +405,11 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
onPressed: () {},
child: Text(
widget.modelManga!.genre![i],
style: const TextStyle(
style: TextStyle(
fontSize: 11.5,
color: Colors.white),
color: isLight(context)
? Colors.black
: Colors.white),
),
),
),
@ -303,6 +431,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
height: 30,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
backgroundColor:
Colors.grey.withOpacity(0.2),
shape: RoundedRectangleBorder(
@ -312,9 +441,11 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
onPressed: () {},
child: Text(
widget.modelManga!.genre![i],
style: const TextStyle(
style: TextStyle(
fontSize: 11.5,
color: Colors.white),
color: isLight(context)
? Colors.black
: Colors.white),
),
),
),
@ -335,7 +466,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
padding:
const EdgeInsets.symmetric(horizontal: 8),
child: Text(
'${widget.modelManga!.chapterTitle!.length.toString()} chapters',
'${widget.modelManga!.chapters!.length.toString()} chapters',
style: const TextStyle(
fontWeight: FontWeight.bold),
),

View file

@ -13,6 +13,19 @@ import 'package:mangayomi/views/more/settings/providers/incognito_mode_state_pro
final isExtended = StateProvider.autoDispose<bool>((ref) {
return true;
});
final isLongPressedProvider = StateProvider.autoDispose<bool>((ref) {
return false;
});
final chapterIndexProvider = StateProvider.autoDispose<int>((ref) => -1);
final chapterModelProvider = StateProvider.autoDispose<ModelChapters>((ref) =>
ModelChapters(
name: "",
url: "",
dateUpload: "",
isBookmarked: false,
scanlator: "",
isRead: false,
lastPageRead: ""));
class MangaDetailsView extends ConsumerStatefulWidget {
final ModelManga modelManga;
@ -57,123 +70,127 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
Widget build(BuildContext context) {
final manga = ref.watch(hiveBoxManga);
return Scaffold(
floatingActionButton: widget.modelManga.chapterTitle!.isNotEmpty
? ValueListenableBuilder<Box>(
valueListenable: ref.watch(hiveBoxMangaInfo).listenable(),
builder: (context, value, child) {
final entries = value.get(
"${widget.modelManga.lang}-${widget.modelManga.source}/${widget.modelManga.name}-chapter_index",
defaultValue: '');
final incognitoMode = ref.watch(incognitoModeStateProvider);
floatingActionButton: ref.watch(isLongPressedProvider) == true
? null
: widget.modelManga.chapters!.isNotEmpty
? ValueListenableBuilder<Box>(
valueListenable: ref.watch(hiveBoxMangaInfo).listenable(),
builder: (context, value, child) {
final entries = value.get(
"${widget.modelManga.lang}-${widget.modelManga.source}/${widget.modelManga.name}-chapter_index",
defaultValue: '');
final incognitoMode = ref.watch(incognitoModeStateProvider);
if (entries.isNotEmpty && !incognitoMode) {
return Consumer(builder: (context, ref, child) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AnimatedContainer(
height: 55,
width: !ref.watch(isExtended) ? 63 : 130,
duration: const Duration(milliseconds: 200),
curve: Curves.easeIn,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: generalColor(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
onPressed: () {
pushMangaReaderView(
context: context,
modelManga: widget.modelManga,
index: int.parse(entries.toString()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.play_arrow,
color: secondaryColor(context),
if (entries.isNotEmpty && !incognitoMode) {
return Consumer(builder: (context, ref, child) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AnimatedContainer(
height: 55,
width: !ref.watch(isExtended) ? 63 : 130,
duration: const Duration(milliseconds: 200),
curve: Curves.easeIn,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: generalColor(context),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(15))),
onPressed: () {
pushMangaReaderView(
context: context,
modelManga: widget.modelManga,
index: int.parse(entries.toString()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Icon(
Icons.play_arrow,
color: Colors.white,
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 8,
duration:
const Duration(milliseconds: 500),
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 60,
duration:
const Duration(milliseconds: 200),
child: const Text(
"Continue",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14, color: Colors.white),
),
),
],
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 8,
duration: const Duration(milliseconds: 500),
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 60,
duration: const Duration(milliseconds: 200),
child: Text(
"Continue",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: secondaryColor(context)),
),
),
],
);
});
}
return Consumer(builder: (context, ref, child) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AnimatedContainer(
height: 55,
width: !ref.watch(isExtended) ? 60 : 105,
duration: const Duration(milliseconds: 300),
curve: Curves.easeIn,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: generalColor(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
onPressed: () {
pushMangaReaderView(
context: context,
modelManga: widget.modelManga,
index:
widget.modelManga.chapters!.length - 1);
},
child: Row(
children: [
const Icon(
Icons.play_arrow,
color: Colors.white,
),
),
],
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 5,
duration: const Duration(milliseconds: 300),
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 40,
duration: const Duration(milliseconds: 300),
child: const Text(
"Read",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: Colors.white,
),
),
),
],
),
),
),
),
],
);
});
}
return Consumer(builder: (context, ref, child) {
return Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
AnimatedContainer(
height: 55,
width: !ref.watch(isExtended) ? 60 : 105,
duration: const Duration(milliseconds: 300),
curve: Curves.easeIn,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: generalColor(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
onPressed: () {
pushMangaReaderView(
context: context,
modelManga: widget.modelManga,
index:
widget.modelManga.chapterTitle!.length - 1);
},
child: Row(
children: [
Icon(
Icons.play_arrow,
color: secondaryColor(context),
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 5,
duration: const Duration(milliseconds: 300),
),
AnimatedContainer(
curve: Curves.easeIn,
width: !ref.watch(isExtended) ? 0 : 40,
duration: const Duration(milliseconds: 300),
child: Text(
"Read",
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14,
color: secondaryColor(context),
),
),
),
],
),
),
),
],
);
});
},
)
: null,
],
);
});
},
)
: null,
body: MangaDetailView(
titleDescription: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -261,16 +278,16 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
genre: widget.modelManga.genre,
author: widget.modelManga.author,
status: widget.modelManga.status,
chapterDate: widget.modelManga.chapterDate,
chapterTitle: widget.modelManga.chapterTitle,
chapterUrl: widget.modelManga.chapterUrl,
description: widget.modelManga.description,
favorite: true,
link: widget.modelManga.link,
source: widget.modelManga.source,
lang: widget.modelManga.lang,
dateAdded: DateTime.now().microsecondsSinceEpoch,
lastUpdate: DateTime.now().microsecondsSinceEpoch);
lastUpdate: DateTime.now().microsecondsSinceEpoch,
chapters: widget.modelManga.chapters,
category: null,
lastRead: '');
manga.put(
'${widget.modelManga.lang}-${widget.modelManga.link}',
model);
@ -310,16 +327,16 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
genre: widget.modelManga.genre,
author: widget.modelManga.author,
status: widget.modelManga.status,
chapterDate: widget.modelManga.chapterDate,
chapterTitle: widget.modelManga.chapterTitle,
chapterUrl: widget.modelManga.chapterUrl,
description: widget.modelManga.description,
favorite: true,
link: widget.modelManga.link,
source: widget.modelManga.source,
lang: widget.modelManga.lang,
dateAdded: DateTime.now().microsecondsSinceEpoch,
lastUpdate: DateTime.now().microsecondsSinceEpoch);
lastUpdate: DateTime.now().microsecondsSinceEpoch,
chapters: widget.modelManga.chapters,
category: null,
lastRead: '');
manga.put(
'${widget.modelManga.lang}-${widget.modelManga.link}',
model);
@ -346,7 +363,7 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
},
),
modelManga: widget.modelManga,
listLength: widget.modelManga.chapterUrl!.length + 1,
listLength: widget.modelManga.chapters!.length + 1,
isExtended: (value) {
ref.read(isExtended.notifier).state = value;
},

View file

@ -48,19 +48,13 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
url: widget.modelManga.link!)
.future)
.then((value) {
if (value.chapterDate.isNotEmpty &&
value.chapterTitle.isNotEmpty &&
value.chapterUrl.isNotEmpty &&
value.chapterDate.length >
widget.modelManga.chapterDate!.length) {
if (value.chapters.isNotEmpty &&
value.chapters.length > widget.modelManga.chapters!.length) {
final model = ModelManga(
imageUrl: widget.modelManga.imageUrl,
name: widget.modelManga.name,
genre: widget.modelManga.genre,
author: widget.modelManga.author,
chapterDate: value.chapterDate,
chapterTitle: value.chapterTitle,
chapterUrl: value.chapterUrl,
description: widget.modelManga.description,
status: value.status,
favorite: _isFavorite,
@ -68,7 +62,10 @@ class _MangaReaderDetailState extends ConsumerState<MangaReaderDetail> {
source: widget.modelManga.source,
lang: widget.modelManga.lang,
dateAdded: widget.modelManga.dateAdded,
lastUpdate: DateTime.now().microsecondsSinceEpoch);
lastUpdate: DateTime.now().microsecondsSinceEpoch,
chapters: value.chapters,
category: null,
lastRead: '');
ref.watch(hiveBoxManga).put(
'${widget.modelManga.lang}-${widget.modelManga.link}',
model);

View file

@ -22,12 +22,12 @@ class ReadMoreWidgetState extends State<ReadMoreWidget>
Stack(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 2),
padding: const EdgeInsets.symmetric(horizontal: 6),
child: ExpandableText(
animationDuration: const Duration(milliseconds: 500),
onExpandedChanged: (ok) {
setState(() => expanded = ok);
widget.onChanged(ok);
onExpandedChanged: (value) {
setState(() => expanded = value);
widget.onChanged(value);
},
expandOnTextTap: true,
widget.text.trim(),

View file

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/models/manga_reader.dart';
import 'package:mangayomi/models/model_manga.dart';
import 'package:mangayomi/utils/colors.dart';
import 'package:mangayomi/utils/utils.dart';
import 'package:mangayomi/views/manga/detail/manga_details_view.dart';
import 'package:mangayomi/views/manga/download/download_page_widget.dart';
class ChapterListTileWidget extends ConsumerWidget {
final List<ModelChapters> chapters;
final ModelManga modelManga;
final bool reverse;
final int reverseIndex;
final int finalIndex;
final bool isLongPressed;
const ChapterListTileWidget(
{super.key,
required this.chapters,
required this.modelManga,
required this.reverse,
required this.reverseIndex,
required this.finalIndex,
required this.isLongPressed});
@override
Widget build(BuildContext context, WidgetRef ref) {
final idx = reverse ? reverseIndex : finalIndex;
final chapterIndex = ref.watch(chapterIndexProvider);
return Container(
color:
chapterIndex == idx ? generalColor(context).withOpacity(0.4) : null,
child: ListTile(
textColor: chapters[finalIndex].isRead
? isLight(context)
? Colors.black.withOpacity(0.4)
: Colors.white.withOpacity(0.3)
: null,
selectedColor: chapters[finalIndex].isRead
? Colors.white.withOpacity(0.3)
: Colors.white,
onLongPress: () {
if (!isLongPressed) {
ref.read(chapterIndexProvider.notifier).state = idx;
ref.read(chapterModelProvider.notifier).state =
chapters[finalIndex];
} else {
ref.read(chapterIndexProvider.notifier).state = -1;
}
ref.read(isLongPressedProvider.notifier).state = !isLongPressed;
},
onTap: () {
if (isLongPressed) {
ref.read(chapterIndexProvider.notifier).state = idx;
ref.read(chapterModelProvider.notifier).state =
chapters[finalIndex];
if (chapterIndex == idx) {
ref.read(chapterIndexProvider.notifier).state = -1;
ref.read(isLongPressedProvider.notifier).state = !isLongPressed;
}
} else {
pushMangaReaderView(
context: context,
modelManga: modelManga,
index: reverse ? reverseIndex : finalIndex);
}
},
title: Row(
children: [
chapters[finalIndex].isBookmarked
? Icon(
Icons.bookmark,
size: 15,
color: generalColor(context),
)
: Container(),
Text(
chapters[finalIndex].name!,
style: const TextStyle(fontSize: 13),
),
],
),
subtitle: Text(
chapters[finalIndex].dateUpload!,
style: const TextStyle(fontSize: 11),
),
trailing: ref.watch(ChapterPageDownloadsProvider(
index: reverse ? reverseIndex : finalIndex,
modelManga: modelManga)),
),
);
}
}

View file

@ -51,9 +51,9 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
final path1 = await _storageProvider.getDirectory();
final finalPath =
"downloads/${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapterTitle![widget.index].replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}";
"downloads/${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapters![widget.index].name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}";
path = Directory(
"${path1!.path}downloads/${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapterTitle![widget.index].replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/");
"${path1!.path}downloads/${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapters![widget.index].name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/");
ref
.read(getMangaChapterUrlProvider(
modelManga: widget.modelManga,
@ -85,7 +85,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
final path3 = Directory(
"${path2.path}${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/");
final path5 = Directory(
"${path2.path}${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapterTitle![widget.index].replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}");
"${path2.path}${widget.modelManga.source} (${widget.modelManga.lang!.toUpperCase()})/${widget.modelManga.name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}/${widget.modelManga.chapters![widget.index].name!.replaceAll(RegExp(r'[^a-zA-Z0-9 .()\-\s]'), '_')}");
if (!(await path1.exists())) {
path1.create();
@ -166,7 +166,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
ref
.watch(hiveBoxMangaDownloads)
.put(widget.modelManga.chapterTitle![widget.index], model);
.put(widget.modelManga.chapters![widget.index].name!, model);
} else {
await FileDownloader().downloadBatch(
tasks,
@ -182,7 +182,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
isStartDownload: true);
Hive.box<DownloadModel>(HiveConstant.hiveBoxDownloads)
.put(widget.modelManga.chapterTitle![widget.index], model);
.put(widget.modelManga.chapters![widget.index].name!, model);
},
taskProgressCallback: (task, progress) async {
if (progress == 1.0) {
@ -216,11 +216,11 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
try {
path!.deleteSync(recursive: true);
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga.chapterTitle![widget.index],
widget.modelManga.chapters![widget.index].name!,
);
} catch (e) {
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga.chapterTitle![widget.index],
widget.modelManga.chapters![widget.index].name!,
);
}
}
@ -239,8 +239,8 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
builder: (context, val, child) {
final entries = val.values
.where((element) =>
element.modelManga.chapterTitle![element.index] ==
widget.modelManga.chapterTitle![widget.index])
element.modelManga.chapters![element.index].name ==
widget.modelManga.chapters![widget.index].name)
.toList();
if (entries.isNotEmpty) {
@ -289,7 +289,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
const Duration(seconds: 1));
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga
.chapterTitle![widget.index],
.chapters![widget.index].name,
);
});
}
@ -366,7 +366,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
const Duration(seconds: 1));
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga
.chapterTitle![widget.index],
.chapters![widget.index].name,
);
});
}
@ -405,7 +405,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
if (value.toString() == 'Retry') {
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga
.chapterTitle![widget.index],
.chapters![widget.index].name,
);
_startDownload();
setState(() {
@ -439,7 +439,7 @@ class _ChapterPageDownloadState extends ConsumerState<ChapterPageDownload>
.then((value) async {
await Future.delayed(const Duration(seconds: 1));
ref.watch(hiveBoxMangaDownloads).delete(
widget.modelManga.chapterTitle![widget.index],
widget.modelManga.chapters![widget.index].name!,
);
});
}

View file

@ -436,7 +436,7 @@ class _MangaChapterPageGalleryState
1 !=
widget.readerController
.getModelManga()
.chapterTitle!
.chapters!
.length
? Colors.white
: Colors.grey,

View file

@ -29,7 +29,7 @@ class CurrentIndex extends _$CurrentIndex {
final incognitoMode = ref.watch(incognitoModeStateProvider);
if (!incognitoMode) {
return ref.watch(hiveBoxMangaInfo).get(
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapterTitle![mangaReaderModel.index]}-page_index",
"${modelManga.lang}-${modelManga.source}/${modelManga.name}/${modelManga.chapters![mangaReaderModel.index].name}-page_index",
defaultValue: 0);
}
return 0;
@ -160,6 +160,6 @@ class ReaderController extends _$ReaderController {
}
String getChapterTitle() {
return getModelManga().chapterTitle![mangaReaderModel.index];
return getModelManga().chapters![mangaReaderModel.index].name!;
}
}

View file

@ -64,7 +64,7 @@ class ReaderModeAdapter extends TypeAdapter<ReaderMode> {
// RiverpodGenerator
// **************************************************************************
String _$currentIndexHash() => r'd7ced153c521783c0cef060c8aeb61112bc4b7aa';
String _$currentIndexHash() => r'287404f12bc984052a83e97beb3ff335e820e8de';
/// Copied from Dart SDK
class _SystemHash {
@ -182,7 +182,7 @@ class CurrentIndexProvider
}
}
String _$readerControllerHash() => r'243aaf5a9eb3aa92f6477876e3d907bd1f45f6d3';
String _$readerControllerHash() => r'01306848356204f0716ab763839d6c9e66051dd1';
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
late final MangaReaderModel mangaReaderModel;

View file

@ -90,7 +90,7 @@ class DownloadQueueScreen extends ConsumerWidget {
],
),
Text(
element.modelManga.chapterTitle![element.index],
element.modelManga.chapters![element.index].name!,
style: const TextStyle(fontSize: 13),
),
const SizedBox(
@ -119,7 +119,7 @@ class DownloadQueueScreen extends ConsumerWidget {
const Duration(seconds: 1));
ref.watch(hiveBoxMangaDownloads).delete(
element.modelManga
.chapterTitle![element.index],
.chapters![element.index].name,
);
});
}

View file

@ -19,7 +19,7 @@ class FlexSchemeColorState extends _$FlexSchemeColorState {
.schemes[ref.watch(hiveBoxSettings).get('FlexColorIndex')].dark;
}
}
return FlexColor.deepBlue.light;
return state;
}
void setTheme(FlexSchemeColor color, int index) {

View file

@ -36,9 +36,6 @@ class _MangaImageCardWidgetState extends ConsumerState<MangaImageCardWidget> {
name: widget.getMangaDetailModel!.name,
genre: widget.getMangaDetailModel!.genre,
author: widget.getMangaDetailModel!.author,
chapterDate: widget.getMangaDetailModel!.chapterDate,
chapterTitle: widget.getMangaDetailModel!.chapterTitle,
chapterUrl: widget.getMangaDetailModel!.chapterUrl,
status: widget.getMangaDetailModel!.status,
description: widget.getMangaDetailModel!.description,
favorite: false,
@ -46,7 +43,10 @@ class _MangaImageCardWidgetState extends ConsumerState<MangaImageCardWidget> {
source: widget.getMangaDetailModel!.source,
lang: widget.lang,
dateAdded: DateTime.now().microsecondsSinceEpoch,
lastUpdate: DateTime.now().microsecondsSinceEpoch);
lastUpdate: DateTime.now().microsecondsSinceEpoch,
chapters: widget.getMangaDetailModel!.chapters,
category: null,
lastRead: '');
if (mounted) {
context.push('/manga-reader/detail', extra: modelManga);
}

View file

@ -585,6 +585,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.2.0"
material_design_icons_flutter:
dependency: "direct main"
description:
name: material_design_icons_flutter
sha256: "8ef8562d16e747b2d93e5da5c2508931588939c5c00ebc8e2768e803db7dfd3c"
url: "https://pub.dev"
source: hosted
version: "6.0.7096"
meta:
dependency: transitive
description:

View file

@ -59,6 +59,7 @@ dependencies:
git:
url: https://github.com/kodjodevf/background_downloader.git
permission_handler: ^10.2.0
material_design_icons_flutter: ^6.0.7096
# The following adds the Cupertino Icons font to your application.