Fix: global search pages rebuild, audios and subtitles $reified as List
This commit is contained in:
parent
eac62fa3b0
commit
dea28e3dd9
22 changed files with 160 additions and 284 deletions
|
|
@ -37,7 +37,7 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
BridgeTypeRef.type(RuntimeTypes.mapType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'substitles',
|
||||
'subtitles',
|
||||
BridgeTypeAnnotation(BridgeTypeRef(CoreTypes.list,
|
||||
[BridgeTypeRef.type(RuntimeTypes.dynamicType)])),
|
||||
false),
|
||||
|
|
@ -58,7 +58,7 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.stringType))),
|
||||
'headers': BridgeFieldDef(
|
||||
BridgeTypeAnnotation(BridgeTypeRef.type(RuntimeTypes.mapType))),
|
||||
'substitles': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
|
||||
'subtitles': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
|
||||
'audios': BridgeFieldDef(BridgeTypeAnnotation(BridgeTypeRef(
|
||||
CoreTypes.list, [BridgeTypeRef.type(RuntimeTypes.dynamicType)]))),
|
||||
|
|
@ -86,11 +86,9 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
return $String($value.quality!);
|
||||
case 'originalUrl':
|
||||
return $String($value.originalUrl!);
|
||||
|
||||
case 'headers':
|
||||
return $Map.wrap($value.headers!);
|
||||
|
||||
case 'substitles':
|
||||
case 'subtitles':
|
||||
return $List.wrap($value.subtitles!
|
||||
.map((e) =>
|
||||
$TrackModel.wrap(TrackModel(file: e.file, label: e.label)))
|
||||
|
|
@ -119,11 +117,26 @@ class $VideoModel implements VideoModel, $Instance {
|
|||
case 'originalUrl':
|
||||
$value.originalUrl = value.$reified;
|
||||
case 'headers':
|
||||
$value.headers = value.$reified as Map<String, String>;
|
||||
$value.headers = (value.$reified as Map).isNotEmpty
|
||||
? (value.$reified as Map)
|
||||
.map((key, value) => MapEntry(key.toString(), value.toString()))
|
||||
: {};
|
||||
case 'subtitles':
|
||||
$value.subtitles = value.$reified as List<TrackModel>;
|
||||
$value.subtitles = (value.$reified as List).isNotEmpty
|
||||
? (value.$reified as List)
|
||||
.map((e) => TrackModel()
|
||||
..file = e.file
|
||||
..label = e.label)
|
||||
.toList()
|
||||
: [];
|
||||
case 'audios':
|
||||
$value.audios = value.$reified as List<TrackModel>;
|
||||
$value.audios = (value.$reified as List).isNotEmpty
|
||||
? (value.$reified as List)
|
||||
.map((e) => TrackModel()
|
||||
..file = e.file
|
||||
..label = e.label)
|
||||
.toList()
|
||||
: [];
|
||||
|
||||
default:
|
||||
_superclass.$setProperty(runtime, identifier, value);
|
||||
|
|
|
|||
|
|
@ -658,10 +658,8 @@ class MBridge {
|
|||
);
|
||||
}
|
||||
|
||||
static Future<List<Video>> doodExtractor(String url) async {
|
||||
return await DoodExtractor().videosFromUrl(
|
||||
url,
|
||||
);
|
||||
static Future<List<Video>> doodExtractor(String url, String? quality) async {
|
||||
return await DoodExtractor().videosFromUrl(url, quality: quality);
|
||||
}
|
||||
|
||||
static Future<List<Video>> streamWishExtractor(
|
||||
|
|
@ -1181,7 +1179,7 @@ class $MBridge extends MBridge with $Bridge {
|
|||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType),
|
||||
nullable: true),
|
||||
false),
|
||||
true),
|
||||
],
|
||||
namedParams: []),
|
||||
isStatic: true),
|
||||
|
|
@ -1763,6 +1761,12 @@ class $MBridge extends MBridge with $Bridge {
|
|||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType)),
|
||||
false),
|
||||
BridgeParameter(
|
||||
'quality',
|
||||
BridgeTypeAnnotation(
|
||||
BridgeTypeRef.type(RuntimeTypes.stringType),
|
||||
nullable: true),
|
||||
true),
|
||||
],
|
||||
namedParams: []),
|
||||
isStatic: true),
|
||||
|
|
@ -2178,7 +2182,7 @@ class $MBridge extends MBridge with $Bridge {
|
|||
|
||||
static $Future<List<$VideoModel>> $doodExtractor(
|
||||
Runtime runtime, $Value? target, List<$Value?> args) =>
|
||||
$Future.wrap(MBridge.doodExtractor(args[0]!.$value).then(
|
||||
$Future.wrap(MBridge.doodExtractor(args[0]!.$value, args[1]?.$value).then(
|
||||
(value) => $List.wrap(value.map((e) => _toVideoModel(e)).toList())));
|
||||
|
||||
static $Future<List<$VideoModel>> $streamTapeExtractor(
|
||||
|
|
@ -2237,7 +2241,7 @@ class $MBridge extends MBridge with $Bridge {
|
|||
|
||||
static $Future<List<$VideoModel>> $voeExtractor(
|
||||
Runtime runtime, $Value? target, List<$Value?> args) =>
|
||||
$Future.wrap(MBridge.voeExtractor(args[0]!.$value, args[1]!.$value).then(
|
||||
$Future.wrap(MBridge.voeExtractor(args[0]!.$value, args[1]?.$value).then(
|
||||
(value) => $List.wrap(value.map((e) => _toVideoModel(e)).toList())));
|
||||
|
||||
static $Future<List<$VideoModel>> $vidBomExtractor(
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'fetch_anime_sources.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$fetchAnimeSourcesListHash() =>
|
||||
r'7aae588d0f4cce365267f9086c67176bf4253989';
|
||||
r'f249fc2761491c8109bdd253d1ec434177f29b21';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'fetch_manga_sources.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$fetchMangaSourcesListHash() =>
|
||||
r'f25ba5350f0d260553bbc53cc4523a68c6fa01b6';
|
||||
r'4830433a410607ed401c6c004af2377c0262a733';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import 'dart:typed_data';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
import 'package:mangayomi/services/search_manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
|
|
@ -35,7 +36,7 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
|||
final _textEditingController = TextEditingController();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
||||
List<Source> sourceList = ref.watch(onlyIncludePinnedSourceStateProvider)
|
||||
? isar.sources
|
||||
.filter()
|
||||
.isPinnedEqualTo(true)
|
||||
|
|
@ -50,6 +51,12 @@ class _GlobalSearchScreenState extends ConsumerState<GlobalSearchScreen> {
|
|||
.and()
|
||||
.isMangaEqualTo(widget.isManga)
|
||||
.findAllSync();
|
||||
sourceList = sourceList
|
||||
.where(
|
||||
(element) =>
|
||||
ref.watch(showNSFWStateProvider) ? true : element.isNsfw == false,
|
||||
)
|
||||
.toList();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: Container(),
|
||||
|
|
@ -118,12 +125,14 @@ class SourceSearchScreen extends ConsumerWidget {
|
|||
ListTile(
|
||||
dense: true,
|
||||
onTap: () {
|
||||
Map<String, dynamic> data = {
|
||||
'query': query,
|
||||
'source': source,
|
||||
'viewOnly': true,
|
||||
};
|
||||
context.push('/searchResult', extra: data);
|
||||
Navigator.push(
|
||||
context,
|
||||
createRoute(
|
||||
page: MangaHomeScreen(
|
||||
query: query,
|
||||
source: source,
|
||||
isSearch: true,
|
||||
)));
|
||||
},
|
||||
title: Text(source.name!),
|
||||
subtitle: Text(
|
||||
|
|
@ -193,7 +202,8 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
context: context,
|
||||
getManga: getMangaDetail,
|
||||
lang: widget.source.lang!,
|
||||
isManga: widget.source.isManga ?? true);
|
||||
isManga: widget.source.isManga ?? true,
|
||||
useMaterialRoute: true);
|
||||
},
|
||||
child: StreamBuilder(
|
||||
stream: isar.mangas
|
||||
|
|
@ -208,7 +218,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
child: Stack(
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
width: 110,
|
||||
child: Column(children: [
|
||||
snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
|
|
@ -216,7 +226,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
? Image.memory(snapshot.data!.first.customCoverImage
|
||||
as Uint8List)
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: cachedNetworkImage(
|
||||
headers: ref.watch(headersProvider(
|
||||
source: getMangaDetail.source!,
|
||||
|
|
@ -226,14 +236,15 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
snapshot.data!.first.imageUrl != null
|
||||
? toImgUrl(snapshot.data!.first.imageUrl!)
|
||||
: toImgUrl(getMangaDetail.imageUrl!),
|
||||
width: 100,
|
||||
height: 140,
|
||||
width: 110,
|
||||
height: 150,
|
||||
fit: BoxFit.fill),
|
||||
),
|
||||
BottomTextWidget(
|
||||
fontSize: 12.0,
|
||||
text: widget.manga.name!,
|
||||
isLoading: true,
|
||||
textColor: Theme.of(context).textTheme.bodyLarge!.color,
|
||||
isComfortableGrid: true,
|
||||
)
|
||||
]),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import 'package:isar/isar.dart';
|
|||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/modules/manga/download/providers/convert_to_cbz.dart';
|
||||
import 'package:mangayomi/modules/more/settings/downloads/providers/downloads_state_provider.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
|
|
@ -42,6 +43,22 @@ Future<List<String>> downloadChapter(
|
|||
"downloads/${isManga ? "Manga" : "Anime"}/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceAll(regExp, '_')}${isManga ? "/$scanlator${chapter.name!.replaceAll(regExp, '_')}" : ""}";
|
||||
path = Directory("${path1!.path}$finalPath/");
|
||||
Map<String, String> videoHeader = {};
|
||||
|
||||
void savePageUrls() {
|
||||
final settings = isar.settings.getSync(227)!;
|
||||
List<ChapterPageurls>? chapterPageUrls = [];
|
||||
for (var chapterPageUrl in settings.chapterPageUrlsList ?? []) {
|
||||
if (chapterPageUrl.chapterId != chapter.id) {
|
||||
chapterPageUrls.add(chapterPageUrl);
|
||||
}
|
||||
}
|
||||
chapterPageUrls.add(ChapterPageurls()
|
||||
..chapterId = chapter.id
|
||||
..urls = pageUrls);
|
||||
isar.writeTxnSync(() =>
|
||||
isar.settings.putSync(settings..chapterPageUrlsList = chapterPageUrls));
|
||||
}
|
||||
|
||||
if (isManga) {
|
||||
ref
|
||||
.read(getChapterUrlProvider(
|
||||
|
|
@ -208,6 +225,7 @@ Future<List<String>> downloadChapter(
|
|||
batchProgressCallback: (succeeded, failed) async {
|
||||
if (succeeded == tasks.length) {
|
||||
if (isManga) {
|
||||
savePageUrls();
|
||||
if (ref.watch(saveAsCBZArchiveStateProvider)) {
|
||||
await ref.watch(convertToCBZProvider(
|
||||
path!.path, mangaDir.path, chapter.name!, pageUrls)
|
||||
|
|
@ -289,6 +307,9 @@ Future<List<String>> downloadChapter(
|
|||
..isDownload = (progress == 1.0));
|
||||
});
|
||||
}
|
||||
if (progress == 1.0) {
|
||||
savePageUrls();
|
||||
}
|
||||
},
|
||||
onStatus: (status) async {
|
||||
if (status == TaskStatus.complete) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'download_provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$downloadChapterHash() => r'66f65a8ecf86c8633ae77f528589d941bc52420e';
|
||||
String _$downloadChapterHash() => r'5d77345658ca2fbc718d74b9e7bb4c52c30e1eaa';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,13 @@ import 'package:mangayomi/modules/widgets/manga_image_card_widget.dart';
|
|||
|
||||
class MangaHomeScreen extends ConsumerStatefulWidget {
|
||||
final Source source;
|
||||
const MangaHomeScreen({required this.source, super.key});
|
||||
final bool isSearch;
|
||||
final String query;
|
||||
const MangaHomeScreen(
|
||||
{required this.source,
|
||||
this.query = "",
|
||||
this.isSearch = false,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<MangaHomeScreen> createState() => _MangaHomeScreenState();
|
||||
|
|
@ -37,7 +43,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
final ScrollController _scrollController = ScrollController();
|
||||
int _fullDataLength = 50;
|
||||
int _page = 1;
|
||||
int _selectedIndex = 0;
|
||||
late int _selectedIndex = widget.isSearch ? 2 : 0;
|
||||
List<TypeMangaSelector> _types(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return [
|
||||
|
|
@ -82,9 +88,9 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
return mangaResList;
|
||||
}
|
||||
|
||||
final _textEditingController = TextEditingController();
|
||||
String _query = "";
|
||||
bool _isSearch = false;
|
||||
late final _textEditingController = TextEditingController(text: widget.query);
|
||||
late String _query = widget.query;
|
||||
late bool _isSearch = widget.isSearch;
|
||||
AsyncValue<List<MangaModel?>>? _getManga;
|
||||
int _length = 0;
|
||||
@override
|
||||
|
|
@ -105,6 +111,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: _isSearch ? null : Text('${widget.source.name}'),
|
||||
leading: !_isSearch ? null : Container(),
|
||||
actions: [
|
||||
_isSearch
|
||||
? SeachFormTextField(
|
||||
|
|
@ -127,11 +134,15 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
},
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = false;
|
||||
_query = "";
|
||||
_selectedIndex = 0;
|
||||
_page = 1;
|
||||
_textEditingController.clear();
|
||||
if (_textEditingController.text.isEmpty) {
|
||||
_isSearch = false;
|
||||
_query = "";
|
||||
_selectedIndex = 0;
|
||||
_page = 1;
|
||||
_textEditingController.clear();
|
||||
} else {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
});
|
||||
},
|
||||
controller: _textEditingController,
|
||||
|
|
@ -189,7 +200,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
|
|||
),
|
||||
Container(
|
||||
color: primaryColor(context),
|
||||
height: 1,
|
||||
height: 0.3,
|
||||
width: mediaWidth(context, 1),
|
||||
)
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,192 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/search_manga.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||
import 'package:mangayomi/modules/widgets/gridview_widget.dart';
|
||||
import 'package:mangayomi/utils/media_query.dart';
|
||||
|
||||
class SearchResultScreen extends ConsumerStatefulWidget {
|
||||
final String query;
|
||||
final Source source;
|
||||
final bool viewOnly;
|
||||
const SearchResultScreen({
|
||||
super.key,
|
||||
required this.query,
|
||||
required this.source,
|
||||
this.viewOnly = false,
|
||||
});
|
||||
|
||||
@override
|
||||
ConsumerState<SearchResultScreen> createState() => _SearchResultScreenState();
|
||||
}
|
||||
|
||||
class _SearchResultScreenState extends ConsumerState<SearchResultScreen> {
|
||||
bool _isLoading = false;
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
int _page = 1;
|
||||
int _length = 0;
|
||||
Future<List<MangaModel?>> _loadMore() async {
|
||||
List<MangaModel?> mangaResList = [];
|
||||
mangaResList = await ref.watch(searchMangaProvider(
|
||||
source: widget.source, query: widget.query, page: _page)
|
||||
.future);
|
||||
if (_isLoading) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_page = _page + 1;
|
||||
});
|
||||
}
|
||||
}
|
||||
return mangaResList;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final search = ref.watch(searchMangaProvider(
|
||||
source: widget.source, query: widget.query, page: _page));
|
||||
return Scaffold(
|
||||
appBar: widget.viewOnly
|
||||
? AppBar(
|
||||
title: Text(widget.query),
|
||||
)
|
||||
: null,
|
||||
body: search.when(
|
||||
loading: () => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
error: (error, stackTrace) => Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
ref.invalidate(searchMangaProvider(
|
||||
source: widget.source,
|
||||
query: widget.query,
|
||||
page: 1));
|
||||
},
|
||||
icon: const Icon(Icons.refresh)),
|
||||
Text(l10n.refresh)
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
error.toString(),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
data: (data) {
|
||||
Widget buildProgressIndicator() {
|
||||
return !(data.isNotEmpty && (data.last!.hasNextPage ?? true))
|
||||
? Container()
|
||||
: _isLoading
|
||||
? const Center(
|
||||
child: SizedBox(
|
||||
height: 100,
|
||||
width: 200,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
),
|
||||
)
|
||||
: isTablet(context)
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(5))),
|
||||
onPressed: () {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
}
|
||||
_loadMore().then((value) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
data.addAll(value);
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(l10n.load_more),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
const Icon(
|
||||
Icons.arrow_forward_outlined),
|
||||
],
|
||||
)),
|
||||
)
|
||||
: Container();
|
||||
}
|
||||
|
||||
if (data.isEmpty) {
|
||||
return Center(child: Text(l10n.no_result));
|
||||
}
|
||||
_scrollController.addListener(() {
|
||||
if (_scrollController.position.pixels ==
|
||||
_scrollController.position.maxScrollExtent) {
|
||||
if (data.isNotEmpty && (data.last!.hasNextPage ?? true)) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
}
|
||||
_loadMore().then((value) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
data.addAll(value);
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
_length = data.length;
|
||||
_length = (data.length < _length ? data.length : _length);
|
||||
return GridViewWidget(
|
||||
controller: _scrollController,
|
||||
itemCount: _length + 1,
|
||||
itemBuilder: (context, index) {
|
||||
if (index == _length) {
|
||||
return buildProgressIndicator();
|
||||
}
|
||||
return MangaHomeImageCard(
|
||||
manga: data[index]!,
|
||||
source: widget.source,
|
||||
isManga: widget.source.isManga ?? true,
|
||||
);
|
||||
},
|
||||
);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ part of 'check_for_update.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$checkForUpdateHash() => r'2b857a33efbdf16c0d3ccdd8217b9ce472de605f';
|
||||
String _$checkForUpdateHash() => r'e32dea3bda782fc470006c1d3758b523629a091d';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@ class BottomTextWidget extends StatelessWidget {
|
|||
final bool isComfortableGrid;
|
||||
final double? fontSize;
|
||||
final int? maxLines;
|
||||
final Color? textColor;
|
||||
const BottomTextWidget(
|
||||
{super.key,
|
||||
required this.text,
|
||||
this.isLoading = false,
|
||||
this.isComfortableGrid = false,
|
||||
this.fontSize = 12.0,
|
||||
this.maxLines = 2});
|
||||
this.maxLines = 2,
|
||||
this.textColor});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -28,7 +30,7 @@ class BottomTextWidget extends StatelessWidget {
|
|||
style: TextStyle(
|
||||
fontSize: fontSize,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: primaryColor(context),
|
||||
color: textColor ?? primaryColor(context),
|
||||
),
|
||||
maxLines: maxLines,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
|
@ -51,10 +53,10 @@ class BottomTextWidget extends StatelessWidget {
|
|||
padding: const EdgeInsets.only(left: 5, bottom: 5),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
color: textColor ?? Colors.white,
|
||||
shadows: const <Shadow>[
|
||||
Shadow(offset: Offset(0.5, 0.9), blurRadius: 3.0)
|
||||
],
|
||||
),
|
||||
|
|
@ -87,10 +89,10 @@ class BottomTextWidget extends StatelessWidget {
|
|||
padding: const EdgeInsets.only(left: 5, bottom: 5),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 13.0,
|
||||
color: Colors.white,
|
||||
shadows: <Shadow>[
|
||||
color: textColor ?? Colors.white,
|
||||
shadows: const <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(0.5, 0.9), blurRadius: 3.0)
|
||||
],
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/eval/bridge_class/model.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
|
@ -106,7 +108,8 @@ void pushToMangaReaderDetail(
|
|||
required BuildContext context,
|
||||
int? archiveId,
|
||||
Manga? mangaM,
|
||||
bool? isManga}) {
|
||||
bool? isManga,
|
||||
bool useMaterialRoute = false}) {
|
||||
int? mangaId;
|
||||
if (archiveId == null) {
|
||||
final manga = mangaM ??
|
||||
|
|
@ -194,5 +197,14 @@ void pushToMangaReaderDetail(
|
|||
);
|
||||
}
|
||||
|
||||
context.push('/manga-reader/detail', extra: mangaId);
|
||||
if (useMaterialRoute) {
|
||||
Navigator.push(
|
||||
context,
|
||||
createRoute(
|
||||
page: MangaReaderDetail(
|
||||
mangaId: mangaId,
|
||||
)));
|
||||
} else {
|
||||
context.push('/manga-reader/detail', extra: mangaId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import 'package:mangayomi/modules/history/history_screen.dart';
|
|||
import 'package:mangayomi/modules/library/library_screen.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_home_screen.dart';
|
||||
import 'package:mangayomi/modules/manga/home/manga_search_screen.dart';
|
||||
import 'package:mangayomi/modules/manga/reader/reader_view.dart';
|
||||
import 'package:mangayomi/modules/more/about/about_screen.dart';
|
||||
import 'package:mangayomi/modules/more/download_queue/download_queue_screen.dart';
|
||||
|
|
@ -291,29 +290,6 @@ class RouterNotifier extends ChangeNotifier {
|
|||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/searchResult",
|
||||
name: "searchResult",
|
||||
builder: (context, state) {
|
||||
final data = state.extra as Map<String, dynamic>;
|
||||
return SearchResultScreen(
|
||||
query: data['query']!,
|
||||
source: data['source']!,
|
||||
viewOnly: data['viewOnly'],
|
||||
);
|
||||
},
|
||||
pageBuilder: (context, state) {
|
||||
final data = state.extra as Map<String, dynamic>;
|
||||
return CustomTransition(
|
||||
key: state.pageKey,
|
||||
child: SearchResultScreen(
|
||||
query: data['query']!,
|
||||
source: data['source']!,
|
||||
viewOnly: data['viewOnly'],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: "/about",
|
||||
name: "about",
|
||||
|
|
@ -476,3 +452,12 @@ class CustomTransition extends CustomTransitionPage {
|
|||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
Route createRoute({required Widget page}) {
|
||||
return PageRouteBuilder(
|
||||
pageBuilder: (context, animation, secondaryAnimation) => page,
|
||||
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
||||
return FadeTransition(opacity: animation, child: child);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,9 @@ Future<(List<Video>, bool)> getAnimeServers(
|
|||
final mangaDirectory = await storageProvider.getMangaMainDirectory(episode);
|
||||
final isLocalArchive = episode.manga.value!.isLocalArchive!;
|
||||
List<Video> video = [];
|
||||
|
||||
if (await File("${mangaDirectory!.path}${episode.name}.mp4").exists() ||
|
||||
isLocalArchive) {
|
||||
final path = isLocalArchive
|
||||
? episode.archivePath
|
||||
: "${mangaDirectory.path}${episode.name}.mp4";
|
||||
final mp4animePath = "${mangaDirectory!.path}${episode.name}.mp4";
|
||||
if (await File(mp4animePath).exists() || isLocalArchive) {
|
||||
final path = isLocalArchive ? episode.archivePath : mp4animePath;
|
||||
return ([Video(path!, episode.name!, path, subtitles: [])], true);
|
||||
}
|
||||
final source =
|
||||
|
|
@ -56,11 +53,23 @@ Future<(List<Video>, bool)> getAnimeServers(
|
|||
var subs = e.subtitles;
|
||||
if (subs is $List) {
|
||||
subtitles = subs.map((e) => Track(e.file, e.label)).toList();
|
||||
} else {
|
||||
try {
|
||||
subtitles = (subs as List<TrackModel>).map((e) {
|
||||
return Track(e.file, e.label);
|
||||
}).toList();
|
||||
} catch (_) {}
|
||||
}
|
||||
List<Track>? audios = [];
|
||||
var auds = e.audios;
|
||||
if (auds is $List) {
|
||||
audios = auds.map((e) => Track(e.file, e.label)).toList();
|
||||
} else {
|
||||
try {
|
||||
audios = (subs as List<TrackModel>).map((e) {
|
||||
return Track(e.file, e.label);
|
||||
}).toList();
|
||||
} catch (_) {}
|
||||
}
|
||||
return Video(e.url, e.quality, e.originalUrl,
|
||||
headers: e.headers, subtitles: subtitles, audios: audios);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_anime_servers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getAnimeServersHash() => r'39f02b0c0b51a78a7c1a67747686909beedc5d0e';
|
||||
String _$getAnimeServersHash() => r'908cdc967253129e94e25f58a8d7df18044ccd3a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_chapter_url.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getChapterUrlHash() => r'330c495774b22fc1fdedb0fa64969cd17e4635f8';
|
||||
String _$getChapterUrlHash() => r'd3836616473c773e79c4b09258fbb7c127a60202';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'get_latest_updates_manga.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getLatestUpdatesMangaHash() =>
|
||||
r'b4de1c71b935893780b02be6a4fa1980651a833d';
|
||||
r'a5d39851af8f86e57147591b2c261298ecaa6a1d';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_manga_detail.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getMangaDetailHash() => r'025ccc11f94f9b69bd85d86833bc261f66b74f7f';
|
||||
String _$getMangaDetailHash() => r'0977fe9466dcf9262e37beb644b7f66be2214d1a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'get_popular_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getPopularMangaHash() => r'f5a1f5a66bad652cb461ef0ed9d30f60ff7a000a';
|
||||
String _$getPopularMangaHash() => r'94fbfc0ba4aca487c3f510263bde2566d7b2bf5a';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'search_manga.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$searchMangaHash() => r'9bbf3d7b3cb8f1aa92201200e6a4616721cd3037';
|
||||
String _$searchMangaHash() => r'd0bfdc659fa6bd6d3664ec80e7c426509f39002c';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -285,10 +285,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: dart_eval
|
||||
sha256: c043685c0ea425c79d324e944a8c3c499f251e118d41103aa3448a4eb95ed7f8
|
||||
sha256: "2b94cab3b22cccb5ea0c3241e1ddbfd57a62fc28c3af855cb2b3cbec7c7a5212"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.3"
|
||||
version: "0.6.5"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ dependencies:
|
|||
path_provider: ^2.1.0
|
||||
# image: ^4.0.17
|
||||
scrollable_positioned_list: ^0.3.5
|
||||
dart_eval: ^0.6.3
|
||||
dart_eval: ^0.6.5
|
||||
# git:
|
||||
# url: https://github.com/kodjodevf/dart_eval.git
|
||||
# ref: 05c54b2
|
||||
|
|
|
|||
Loading…
Reference in a new issue