add novel support
This commit is contained in:
parent
b2e25d26de
commit
fb127f56b5
21 changed files with 349 additions and 97 deletions
|
|
@ -1122,6 +1122,10 @@ Settings _settingsDeserialize(
|
|||
libraryFilterMangasDownloadType: reader.readLongOrNull(offsets[53]),
|
||||
libraryFilterMangasStartedType: reader.readLongOrNull(offsets[54]),
|
||||
libraryFilterMangasUnreadType: reader.readLongOrNull(offsets[55]),
|
||||
libraryFilterNovelBookMarkedType: reader.readLongOrNull(offsets[56]),
|
||||
libraryFilterNovelDownloadType: reader.readLongOrNull(offsets[57]),
|
||||
libraryFilterNovelStartedType: reader.readLongOrNull(offsets[58]),
|
||||
libraryFilterNovelUnreadType: reader.readLongOrNull(offsets[59]),
|
||||
libraryLocalSource: reader.readBoolOrNull(offsets[60]),
|
||||
libraryShowCategoryTabs: reader.readBoolOrNull(offsets[61]),
|
||||
libraryShowContinueReadingButton: reader.readBoolOrNull(offsets[62]),
|
||||
|
|
@ -1132,6 +1136,15 @@ Settings _settingsDeserialize(
|
|||
reader.readByteOrNull(offsets[67])] ??
|
||||
DisplayType.comfortableGrid,
|
||||
markEpisodeAsSeenType: reader.readLongOrNull(offsets[68]),
|
||||
novelDisplayType: _SettingsnovelDisplayTypeValueEnumMap[
|
||||
reader.readByteOrNull(offsets[69])] ??
|
||||
DisplayType.comfortableGrid,
|
||||
novelLibraryDownloadedChapters: reader.readBoolOrNull(offsets[71]),
|
||||
novelLibraryLocalSource: reader.readBoolOrNull(offsets[72]),
|
||||
novelLibraryShowCategoryTabs: reader.readBoolOrNull(offsets[73]),
|
||||
novelLibraryShowContinueReadingButton: reader.readBoolOrNull(offsets[74]),
|
||||
novelLibraryShowLanguage: reader.readBoolOrNull(offsets[75]),
|
||||
novelLibraryShowNumbersOfItems: reader.readBoolOrNull(offsets[76]),
|
||||
onlyIncludePinnedSources: reader.readBoolOrNull(offsets[77]),
|
||||
pagePreloadAmount: reader.readLongOrNull(offsets[78]),
|
||||
personalPageModeList: reader.readObjectList<PersonalPageMode>(
|
||||
|
|
@ -1174,6 +1187,11 @@ Settings _settingsDeserialize(
|
|||
SortLibraryMangaSchema.deserialize,
|
||||
allOffsets,
|
||||
),
|
||||
sortLibraryNovel: reader.readObjectOrNull<SortLibraryManga>(
|
||||
offsets[90],
|
||||
SortLibraryMangaSchema.deserialize,
|
||||
allOffsets,
|
||||
),
|
||||
startDatebackup: reader.readLongOrNull(offsets[91]),
|
||||
syncAfterReading: reader.readBoolOrNull(offsets[92]),
|
||||
syncOnAppLaunch: reader.readBoolOrNull(offsets[93]),
|
||||
|
|
@ -1202,31 +1220,12 @@ Settings _settingsDeserialize(
|
|||
allOffsets,
|
||||
FilterScanlator(),
|
||||
);
|
||||
object.libraryFilterNovelBookMarkedType = reader.readLongOrNull(offsets[56]);
|
||||
object.libraryFilterNovelDownloadType = reader.readLongOrNull(offsets[57]);
|
||||
object.libraryFilterNovelStartedType = reader.readLongOrNull(offsets[58]);
|
||||
object.libraryFilterNovelUnreadType = reader.readLongOrNull(offsets[59]);
|
||||
object.locale = reader.readObjectOrNull<L10nLocale>(
|
||||
offsets[65],
|
||||
L10nLocaleSchema.deserialize,
|
||||
allOffsets,
|
||||
);
|
||||
object.novelDisplayType = _SettingsnovelDisplayTypeValueEnumMap[
|
||||
reader.readByteOrNull(offsets[69])] ??
|
||||
DisplayType.compactGrid;
|
||||
object.novelGridSize = reader.readLongOrNull(offsets[70]);
|
||||
object.novelLibraryDownloadedChapters = reader.readBoolOrNull(offsets[71]);
|
||||
object.novelLibraryLocalSource = reader.readBoolOrNull(offsets[72]);
|
||||
object.novelLibraryShowCategoryTabs = reader.readBoolOrNull(offsets[73]);
|
||||
object.novelLibraryShowContinueReadingButton =
|
||||
reader.readBoolOrNull(offsets[74]);
|
||||
object.novelLibraryShowLanguage = reader.readBoolOrNull(offsets[75]);
|
||||
object.novelLibraryShowNumbersOfItems = reader.readBoolOrNull(offsets[76]);
|
||||
object.sortLibraryNovel = reader.readObjectOrNull<SortLibraryManga>(
|
||||
offsets[90],
|
||||
SortLibraryMangaSchema.deserialize,
|
||||
allOffsets,
|
||||
);
|
||||
return object;
|
||||
}
|
||||
|
||||
|
|
@ -1439,7 +1438,7 @@ P _settingsDeserializeProp<P>(
|
|||
case 69:
|
||||
return (_SettingsnovelDisplayTypeValueEnumMap[
|
||||
reader.readByteOrNull(offset)] ??
|
||||
DisplayType.compactGrid) as P;
|
||||
DisplayType.comfortableGrid) as P;
|
||||
case 70:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 71:
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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/models/source.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/providers/storage_provider.dart';
|
||||
|
|
@ -75,8 +76,9 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
)
|
||||
: Row(
|
||||
children: [
|
||||
if (_tabBarController.index == 2 ||
|
||||
_tabBarController.index == 3)
|
||||
if (_tabBarController.index == 3 ||
|
||||
_tabBarController.index == 4 ||
|
||||
_tabBarController.index == 5)
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.push('/createExtension');
|
||||
|
|
@ -87,8 +89,9 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
? IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
if (_tabBarController.index != 1 &&
|
||||
_tabBarController.index != 0) {
|
||||
if (_tabBarController.index != 0 &&
|
||||
_tabBarController.index != 1 &&
|
||||
_tabBarController.index != 2) {
|
||||
setState(() {
|
||||
_isSearch = true;
|
||||
});
|
||||
|
|
@ -101,7 +104,8 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
},
|
||||
icon: Icon(
|
||||
_tabBarController.index == 0 ||
|
||||
_tabBarController.index == 1
|
||||
_tabBarController.index == 1 ||
|
||||
_tabBarController.index == 2
|
||||
? Icons.travel_explore_rounded
|
||||
: Icons.search_rounded,
|
||||
color: Theme.of(context).hintColor))
|
||||
|
|
@ -116,18 +120,24 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
} else if (_tabBarController.index == 1) {
|
||||
context.push('/sourceFilter', extra: false);
|
||||
} else if (_tabBarController.index == 2) {
|
||||
_textEditingController.clear();
|
||||
context.push('/ExtensionLang', extra: true);
|
||||
context.push('/sourceFilter', extra: false);
|
||||
} else if (_tabBarController.index == 3) {
|
||||
_textEditingController.clear();
|
||||
context.push('/ExtensionLang', extra: false);
|
||||
} else if (_tabBarController.index == 4) {
|
||||
_textEditingController.clear();
|
||||
context.push('/ExtensionLang', extra: false);
|
||||
} else if (_tabBarController.index == 5) {
|
||||
_textEditingController.clear();
|
||||
context.push('/ExtensionLang', extra: false);
|
||||
} else {}
|
||||
},
|
||||
icon: Icon(
|
||||
_tabBarController.index == 0 || _tabBarController.index == 1
|
||||
_tabBarController.index == 0 || _tabBarController.index == 1 || _tabBarController.index == 2
|
||||
? Icons.filter_list_sharp
|
||||
: _tabBarController.index == 2 ||
|
||||
_tabBarController.index == 3
|
||||
: _tabBarController.index == 3 ||
|
||||
_tabBarController.index == 4 ||
|
||||
_tabBarController.index == 5
|
||||
? Icons.translate_rounded
|
||||
: Icons.help_outline_outlined,
|
||||
color: Theme.of(context).hintColor)),
|
||||
|
|
@ -139,12 +149,13 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
tabs: [
|
||||
Tab(text: l10n.manga_sources),
|
||||
Tab(text: l10n.anime_sources),
|
||||
Tab(text: l10n.novel_sources),
|
||||
Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.manga_extensions),
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, true)
|
||||
_extensionUpdateNumbers(ref, ItemType.manga)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -153,7 +164,16 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
children: [
|
||||
Text(l10n.anime_extensions),
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, false)
|
||||
_extensionUpdateNumbers(ref, ItemType.anime)
|
||||
],
|
||||
),
|
||||
),
|
||||
Tab(
|
||||
child: Row(
|
||||
children: [
|
||||
Text(l10n.novel_extensions),
|
||||
const SizedBox(width: 8),
|
||||
_extensionUpdateNumbers(ref, ItemType.novel)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -163,24 +183,34 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
),
|
||||
body: TabBarView(controller: _tabBarController, children: [
|
||||
SourcesScreen(
|
||||
isManga: true,
|
||||
itemType: ItemType.manga,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
SourcesScreen(
|
||||
isManga: false,
|
||||
itemType: ItemType.anime,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
SourcesScreen(
|
||||
itemType: ItemType.novel,
|
||||
tabIndex: (index) {
|
||||
_tabBarController.animateTo(index);
|
||||
},
|
||||
),
|
||||
ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
isManga: true,
|
||||
itemType: ItemType.manga,
|
||||
),
|
||||
ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
isManga: false,
|
||||
itemType: ItemType.anime,
|
||||
),
|
||||
ExtensionScreen(
|
||||
query: _textEditingController.text,
|
||||
itemType: ItemType.novel,
|
||||
),
|
||||
// const MigrateScreen()
|
||||
]),
|
||||
|
|
@ -189,14 +219,14 @@ class _BrowseScreenState extends ConsumerState<BrowseScreen>
|
|||
}
|
||||
}
|
||||
|
||||
Widget _extensionUpdateNumbers(WidgetRef ref, bool isManga) {
|
||||
Widget _extensionUpdateNumbers(WidgetRef ref, ItemType itemType) {
|
||||
return StreamBuilder(
|
||||
stream: isar.sources
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.isActiveEqualTo(true)
|
||||
.isMangaEqualTo(isManga)
|
||||
.itemTypeEqualTo(itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:grouped_list/sliver_grouped_list.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/providers/extensions_provider.dart';
|
||||
import 'package:mangayomi/services/fetch_anime_sources.dart';
|
||||
import 'package:mangayomi/services/fetch_manga_sources.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/services/fetch_novel_sources.dart';
|
||||
import 'package:mangayomi/services/fetch_sources_list.dart';
|
||||
import 'package:mangayomi/utils/language.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/widgets/extension_list_tile_widget.dart';
|
||||
|
||||
class ExtensionScreen extends ConsumerStatefulWidget {
|
||||
final bool isManga;
|
||||
final ItemType itemType;
|
||||
final String query;
|
||||
const ExtensionScreen(
|
||||
{required this.query, required this.isManga, super.key});
|
||||
{required this.query, required this.itemType, super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<ExtensionScreen> createState() => _ExtensionScreenState();
|
||||
|
|
@ -26,19 +28,24 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final streamExtensions =
|
||||
ref.watch(getExtensionsStreamProvider(widget.isManga));
|
||||
if (widget.isManga) {
|
||||
ref.watch(getExtensionsStreamProvider(widget.itemType));
|
||||
if (widget.itemType == ItemType.manga) {
|
||||
ref.watch(fetchMangaSourcesListProvider(id: null, reFresh: false));
|
||||
} else {
|
||||
} else if (widget.itemType == ItemType.anime) {
|
||||
ref.watch(fetchAnimeSourcesListProvider(id: null, reFresh: false));
|
||||
} else {
|
||||
ref.watch(fetchNovelSourcesListProvider(id: null, reFresh: false));
|
||||
}
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => widget.isManga
|
||||
onRefresh: () => widget.itemType == ItemType.manga
|
||||
? ref.refresh(
|
||||
fetchMangaSourcesListProvider(id: null, reFresh: true).future)
|
||||
: ref.refresh(
|
||||
fetchAnimeSourcesListProvider(id: null, reFresh: true).future),
|
||||
: widget.itemType == ItemType.anime
|
||||
? ref.refresh(
|
||||
fetchAnimeSourcesListProvider(id: null, reFresh: true).future) :
|
||||
ref.refresh(
|
||||
fetchNovelSourcesListProvider(id: null, reFresh: true).future),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: streamExtensions.when(
|
||||
|
|
@ -87,14 +94,19 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
|||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
for (var source in updateEntries) {
|
||||
source.isManga!
|
||||
source.itemType == ItemType.manga
|
||||
? await ref.watch(
|
||||
fetchMangaSourcesListProvider(
|
||||
id: source.id, reFresh: true)
|
||||
.future)
|
||||
: await ref.watch(
|
||||
: source.itemType == ItemType.anime ?
|
||||
await ref.watch(
|
||||
fetchAnimeSourcesListProvider(
|
||||
id: source.id, reFresh: true)
|
||||
.future) :
|
||||
await ref.watch(
|
||||
fetchNovelSourcesListProvider(
|
||||
id: source.id, reFresh: true)
|
||||
.future);
|
||||
}
|
||||
},
|
||||
|
|
@ -167,12 +179,15 @@ class _ExtensionScreenState extends ConsumerState<ExtensionScreen> {
|
|||
error: (error, _) => Center(
|
||||
child: ElevatedButton(
|
||||
onPressed: () {
|
||||
if (widget.isManga) {
|
||||
if (widget.itemType == ItemType.manga) {
|
||||
ref.invalidate(
|
||||
fetchMangaSourcesListProvider(id: null, reFresh: true));
|
||||
} else {
|
||||
} else if (widget.itemType == ItemType.anime) {
|
||||
ref.invalidate(
|
||||
fetchAnimeSourcesListProvider(id: null, reFresh: true));
|
||||
} else {
|
||||
ref.invalidate(
|
||||
fetchNovelSourcesListProvider(id: null, reFresh: true));
|
||||
}
|
||||
},
|
||||
child: Text(context.l10n.refresh)),
|
||||
|
|
|
|||
|
|
@ -1,17 +1,18 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'extensions_provider.g.dart';
|
||||
|
||||
@riverpod
|
||||
Stream<List<Source>> getExtensionsStream(Ref ref, bool? isManga) async* {
|
||||
Stream<List<Source>> getExtensionsStream(Ref ref, ItemType itemType) async* {
|
||||
yield* isar.sources
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.isActiveEqualTo(true)
|
||||
.isMangaEqualTo(isManga)
|
||||
.itemTypeEqualTo(itemType)
|
||||
.watch(fireImmediately: true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'extensions_provider.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getExtensionsStreamHash() =>
|
||||
r'62f2884dd64a2f3d8928f7399c6b2547f0311078';
|
||||
r'3c5d6625c40c222f25fc8141df078dd46bcc762f';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -41,10 +41,10 @@ class GetExtensionsStreamFamily extends Family<AsyncValue<List<Source>>> {
|
|||
|
||||
/// See also [getExtensionsStream].
|
||||
GetExtensionsStreamProvider call(
|
||||
bool? isManga,
|
||||
ItemType itemType,
|
||||
) {
|
||||
return GetExtensionsStreamProvider(
|
||||
isManga,
|
||||
itemType,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ class GetExtensionsStreamFamily extends Family<AsyncValue<List<Source>>> {
|
|||
covariant GetExtensionsStreamProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.isManga,
|
||||
provider.itemType,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -77,11 +77,11 @@ class GetExtensionsStreamProvider
|
|||
extends AutoDisposeStreamProvider<List<Source>> {
|
||||
/// See also [getExtensionsStream].
|
||||
GetExtensionsStreamProvider(
|
||||
bool? isManga,
|
||||
ItemType itemType,
|
||||
) : this._internal(
|
||||
(ref) => getExtensionsStream(
|
||||
ref as GetExtensionsStreamRef,
|
||||
isManga,
|
||||
itemType,
|
||||
),
|
||||
from: getExtensionsStreamProvider,
|
||||
name: r'getExtensionsStreamProvider',
|
||||
|
|
@ -92,7 +92,7 @@ class GetExtensionsStreamProvider
|
|||
dependencies: GetExtensionsStreamFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
GetExtensionsStreamFamily._allTransitiveDependencies,
|
||||
isManga: isManga,
|
||||
itemType: itemType,
|
||||
);
|
||||
|
||||
GetExtensionsStreamProvider._internal(
|
||||
|
|
@ -102,10 +102,10 @@ class GetExtensionsStreamProvider
|
|||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.isManga,
|
||||
required this.itemType,
|
||||
}) : super.internal();
|
||||
|
||||
final bool? isManga;
|
||||
final ItemType itemType;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
|
|
@ -120,7 +120,7 @@ class GetExtensionsStreamProvider
|
|||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
isManga: isManga,
|
||||
itemType: itemType,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -132,13 +132,13 @@ class GetExtensionsStreamProvider
|
|||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is GetExtensionsStreamProvider && other.isManga == isManga;
|
||||
return other is GetExtensionsStreamProvider && other.itemType == itemType;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, isManga.hashCode);
|
||||
hash = _SystemHash.combine(hash, itemType.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
|
|
@ -147,8 +147,8 @@ class GetExtensionsStreamProvider
|
|||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin GetExtensionsStreamRef on AutoDisposeStreamProviderRef<List<Source>> {
|
||||
/// The parameter `isManga` of this provider.
|
||||
bool? get isManga;
|
||||
/// The parameter `itemType` of this provider.
|
||||
ItemType get itemType;
|
||||
}
|
||||
|
||||
class _GetExtensionsStreamProviderElement
|
||||
|
|
@ -157,7 +157,7 @@ class _GetExtensionsStreamProviderElement
|
|||
_GetExtensionsStreamProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
bool? get isManga => (origin as GetExtensionsStreamProvider).isManga;
|
||||
ItemType get itemType => (origin as GetExtensionsStreamProvider).itemType;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|||
import 'package:grouped_list/sliver_grouped_list.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/browse/sources/widgets/source_list_tile.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
|
|
@ -10,9 +11,9 @@ import 'package:mangayomi/utils/language.dart';
|
|||
|
||||
class SourcesScreen extends ConsumerStatefulWidget {
|
||||
final Function(int) tabIndex;
|
||||
final bool isManga;
|
||||
final ItemType itemType;
|
||||
const SourcesScreen(
|
||||
{required this.tabIndex, required this.isManga, super.key});
|
||||
{required this.tabIndex, required this.itemType, super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<SourcesScreen> createState() => _SourcesScreenState();
|
||||
|
|
@ -33,7 +34,7 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
.and()
|
||||
.isActiveEqualTo(true)
|
||||
.and()
|
||||
.isMangaEqualTo(widget.isManga)
|
||||
.itemTypeEqualTo(widget.itemType)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (!snapshot.hasData) {
|
||||
|
|
@ -52,7 +53,7 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
padding: const EdgeInsets.all(8.0),
|
||||
child: ElevatedButton.icon(
|
||||
onPressed: () =>
|
||||
widget.tabIndex(widget.isManga ? 2 : 3),
|
||||
widget.tabIndex(widget.itemType == ItemType.manga ? 3 : widget.itemType == ItemType.anime ? 4 : 5),
|
||||
icon: const Icon(Icons.extension_rounded),
|
||||
label: Text(context.l10n.show_extensions)),
|
||||
)
|
||||
|
|
@ -91,7 +92,7 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
itemBuilder: (context, Source element) {
|
||||
return SourceListTile(
|
||||
source: element,
|
||||
isManga: widget.isManga,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
},
|
||||
groupComparator: (group1, group2) =>
|
||||
|
|
@ -118,7 +119,7 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
itemBuilder: (context, Source element) {
|
||||
return SourceListTile(
|
||||
source: element,
|
||||
isManga: widget.isManga,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
},
|
||||
groupComparator: (group1, group2) =>
|
||||
|
|
@ -146,7 +147,7 @@ class _SourcesScreenState extends ConsumerState<SourcesScreen> {
|
|||
itemBuilder: (context, Source element) {
|
||||
return SourceListTile(
|
||||
source: element,
|
||||
isManga: widget.isManga,
|
||||
itemType: widget.itemType,
|
||||
);
|
||||
},
|
||||
groupComparator: (group1, group2) =>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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/models/source.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
|
|
@ -10,10 +11,10 @@ import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
|||
import 'package:mangayomi/utils/language.dart';
|
||||
|
||||
class SourceListTile extends StatelessWidget {
|
||||
final bool isManga;
|
||||
final ItemType itemType;
|
||||
final Source source;
|
||||
const SourceListTile(
|
||||
{super.key, required this.source, required this.isManga});
|
||||
{super.key, required this.source, required this.itemType});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
|
@ -23,7 +24,7 @@ class SourceListTile extends StatelessWidget {
|
|||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
.isMangaEqualTo(isManga)
|
||||
.itemTypeEqualTo(itemType)
|
||||
.findAllSync();
|
||||
isar.writeTxnSync(() {
|
||||
for (var src in sources) {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen>
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_tabBarController = TabController(length: 2, vsync: this);
|
||||
_tabBarController = TabController(length: 3, vsync: this);
|
||||
_tabBarController.animateTo(0);
|
||||
_tabBarController.addListener(() {
|
||||
setState(() {
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'isar_providers.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getAllHistoryStreamHash() =>
|
||||
r'53b3a7837efab9e7d2808930e5070dbd788c59f8';
|
||||
r'42048cb03035be55b52fc501fb2309cdb2acfcb8';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -161,7 +161,7 @@ class _GetAllHistoryStreamProviderElement
|
|||
}
|
||||
|
||||
String _$getAllUpdateStreamHash() =>
|
||||
r'01f77807c8be11f471b6acee6e7bc358ce600a65';
|
||||
r'6a20f8feba3010c2ab7a80560f7a7f6cf10c7366';
|
||||
|
||||
/// See also [getAllUpdateStream].
|
||||
@ProviderFor(getAllUpdateStream)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'add_torrent.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$addTorrentFromUrlOrFromFileHash() =>
|
||||
r'8102259b30765a5c5cc57870f5c583bd5d421eee';
|
||||
r'11cc239bb8b517326f9a005b0c89dd5eb1127099';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'isar_providers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$getAllMangaStreamHash() => r'1c0b5442ae86b2fa899d509a555f5d375f0ff79a';
|
||||
String _$getAllMangaStreamHash() => r'5e86a22a68ca1a52aefa9c0bc675d284369beac5';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
@ -176,7 +176,7 @@ class _GetAllMangaStreamProviderElement
|
|||
}
|
||||
|
||||
String _$getAllMangaWithoutCategoriesStreamHash() =>
|
||||
r'78076f291274b7defd9567e55314002d9aeecab1';
|
||||
r'61ea54070c7e87a45aeabce5fd21366faaf4ae6d';
|
||||
|
||||
/// See also [getAllMangaWithoutCategoriesStream].
|
||||
@ProviderFor(getAllMangaWithoutCategoriesStream)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'local_archive.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$importArchivesFromFileHash() =>
|
||||
r'8be95f0947ab5247e3305a355a6f17f0aaecad00';
|
||||
r'8e6e592c927ad080e93d54dac1144ef8637a7e52';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ class MainScreen extends ConsumerWidget {
|
|||
int currentIndex = switch (location) {
|
||||
null || '/MangaLibrary' => 0,
|
||||
'/AnimeLibrary' => 1,
|
||||
'/updates' => 2,
|
||||
'/history' => 3,
|
||||
'/browse' => 4,
|
||||
'/NovelLibrary' => 5,
|
||||
'/NovelLibrary' => 2,
|
||||
'/updates' => 3,
|
||||
'/history' => 4,
|
||||
'/browse' => 5,
|
||||
_ => 6,
|
||||
};
|
||||
|
||||
|
|
@ -259,6 +259,12 @@ class MainScreen extends ConsumerWidget {
|
|||
icon: const Icon(
|
||||
Icons.video_collection_outlined),
|
||||
label: l10n.anime),
|
||||
NavigationDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.local_library),
|
||||
icon: const Icon(
|
||||
Icons.local_library_outlined),
|
||||
label: l10n.novel),
|
||||
Stack(
|
||||
children: [
|
||||
NavigationDestination(
|
||||
|
|
@ -298,9 +304,10 @@ class MainScreen extends ConsumerWidget {
|
|||
final fn = switch (newIndex) {
|
||||
0 => route.go('/MangaLibrary'),
|
||||
1 => route.go('/AnimeLibrary'),
|
||||
2 => route.go('/updates'),
|
||||
3 => route.go('/history'),
|
||||
4 => route.go('/browse'),
|
||||
2 => route.go('/NovelLibrary'),
|
||||
3 => route.go('/updates'),
|
||||
4 => route.go('/history'),
|
||||
5 => route.go('/browse'),
|
||||
_ => route.go('/more'),
|
||||
};
|
||||
fn;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'migration.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$migrationHash() => r'a302c6da3c1545c952a28e76a6d0b7af3fde1e7a';
|
||||
String _$migrationHash() => r'403da626b6a797854dde7ae77b4ea452300c40e6';
|
||||
|
||||
/// See also [migration].
|
||||
@ProviderFor(migration)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$updateMangaDetailHash() => r'29a10d49454febb4fe88ca9c007d3512d812bf84';
|
||||
String _$updateMangaDetailHash() => r'a058dcca7f99974e89fce2aa7f048edf1a0f7854';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'download_provider.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$downloadChapterHash() => r'f407f5839eff9754f9590f2f2189bcb604f3fa06';
|
||||
String _$downloadChapterHash() => r'0c9c5baacb970a0f8b105212a4e420e759a38fda';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class _CategoriesScreenState extends ConsumerState<CategoriesScreen>
|
|||
late TabController _tabBarController;
|
||||
@override
|
||||
void initState() {
|
||||
_tabBarController = TabController(length: 2, vsync: this);
|
||||
_tabBarController = TabController(length: 3, vsync: this);
|
||||
_tabBarController.animateTo(widget.data.$2);
|
||||
|
||||
super.initState();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'isar_providers.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$getMangaCategorieStreamHash() =>
|
||||
r'97e90977f4696eedcf597c655a40dd6ccd47ed37';
|
||||
r'1dcf15018a6467eef7a26c1728b9e531ebd984d0';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
|
|||
|
||||
@override
|
||||
void initState() {
|
||||
_tabBarController = TabController(length: 2, vsync: this);
|
||||
_tabBarController = TabController(length: 3, vsync: this);
|
||||
_tabBarController.animateTo(0);
|
||||
_tabBarController.addListener(() {
|
||||
setState(() {
|
||||
|
|
|
|||
19
lib/services/fetch_novel_sources.dart
Normal file
19
lib/services/fetch_novel_sources.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
|
||||
import 'package:mangayomi/services/fetch_sources_list.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
part 'fetch_novel_sources.g.dart';
|
||||
|
||||
@riverpod
|
||||
Future fetchNovelSourcesList(Ref ref,
|
||||
{int? id, required reFresh}) async {
|
||||
if (ref.watch(checkForExtensionsUpdateStateProvider) || reFresh) {
|
||||
await fetchSourcesList(
|
||||
sourcesIndexUrl:
|
||||
"https://kodjodevf.github.io/mangayomi-extensions/index.json",
|
||||
refresh: reFresh,
|
||||
id: id,
|
||||
ref: ref,
|
||||
isManga: true);
|
||||
}
|
||||
}
|
||||
179
lib/services/fetch_novel_sources.g.dart
Normal file
179
lib/services/fetch_novel_sources.g.dart
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'fetch_novel_sources.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$fetchNovelSourcesListHash() =>
|
||||
r'110b23568136e32ebfba7e5414bdf524881a8579';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
_SystemHash._();
|
||||
|
||||
static int combine(int hash, int value) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + value);
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
|
||||
return hash ^ (hash >> 6);
|
||||
}
|
||||
|
||||
static int finish(int hash) {
|
||||
// ignore: parameter_assignments
|
||||
hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
|
||||
// ignore: parameter_assignments
|
||||
hash = hash ^ (hash >> 11);
|
||||
return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
|
||||
}
|
||||
}
|
||||
|
||||
/// See also [fetchNovelSourcesList].
|
||||
@ProviderFor(fetchNovelSourcesList)
|
||||
const fetchNovelSourcesListProvider = FetchNovelSourcesListFamily();
|
||||
|
||||
/// See also [fetchNovelSourcesList].
|
||||
class FetchNovelSourcesListFamily extends Family<AsyncValue> {
|
||||
/// See also [fetchNovelSourcesList].
|
||||
const FetchNovelSourcesListFamily();
|
||||
|
||||
/// See also [fetchNovelSourcesList].
|
||||
FetchNovelSourcesListProvider call({
|
||||
int? id,
|
||||
required dynamic reFresh,
|
||||
}) {
|
||||
return FetchNovelSourcesListProvider(
|
||||
id: id,
|
||||
reFresh: reFresh,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
FetchNovelSourcesListProvider getProviderOverride(
|
||||
covariant FetchNovelSourcesListProvider provider,
|
||||
) {
|
||||
return call(
|
||||
id: provider.id,
|
||||
reFresh: provider.reFresh,
|
||||
);
|
||||
}
|
||||
|
||||
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'fetchNovelSourcesListProvider';
|
||||
}
|
||||
|
||||
/// See also [fetchNovelSourcesList].
|
||||
class FetchNovelSourcesListProvider extends AutoDisposeFutureProvider<Object?> {
|
||||
/// See also [fetchNovelSourcesList].
|
||||
FetchNovelSourcesListProvider({
|
||||
int? id,
|
||||
required dynamic reFresh,
|
||||
}) : this._internal(
|
||||
(ref) => fetchNovelSourcesList(
|
||||
ref as FetchNovelSourcesListRef,
|
||||
id: id,
|
||||
reFresh: reFresh,
|
||||
),
|
||||
from: fetchNovelSourcesListProvider,
|
||||
name: r'fetchNovelSourcesListProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$fetchNovelSourcesListHash,
|
||||
dependencies: FetchNovelSourcesListFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
FetchNovelSourcesListFamily._allTransitiveDependencies,
|
||||
id: id,
|
||||
reFresh: reFresh,
|
||||
);
|
||||
|
||||
FetchNovelSourcesListProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
required super.allTransitiveDependencies,
|
||||
required super.debugGetCreateSourceHash,
|
||||
required super.from,
|
||||
required this.id,
|
||||
required this.reFresh,
|
||||
}) : super.internal();
|
||||
|
||||
final int? id;
|
||||
final dynamic reFresh;
|
||||
|
||||
@override
|
||||
Override overrideWith(
|
||||
FutureOr<Object?> Function(FetchNovelSourcesListRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: FetchNovelSourcesListProvider._internal(
|
||||
(ref) => create(ref as FetchNovelSourcesListRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
debugGetCreateSourceHash: null,
|
||||
id: id,
|
||||
reFresh: reFresh,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
AutoDisposeFutureProviderElement<Object?> createElement() {
|
||||
return _FetchNovelSourcesListProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is FetchNovelSourcesListProvider &&
|
||||
other.id == id &&
|
||||
other.reFresh == reFresh;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode {
|
||||
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||
hash = _SystemHash.combine(hash, id.hashCode);
|
||||
hash = _SystemHash.combine(hash, reFresh.hashCode);
|
||||
|
||||
return _SystemHash.finish(hash);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
mixin FetchNovelSourcesListRef on AutoDisposeFutureProviderRef<Object?> {
|
||||
/// The parameter `id` of this provider.
|
||||
int? get id;
|
||||
|
||||
/// The parameter `reFresh` of this provider.
|
||||
dynamic get reFresh;
|
||||
}
|
||||
|
||||
class _FetchNovelSourcesListProviderElement
|
||||
extends AutoDisposeFutureProviderElement<Object?>
|
||||
with FetchNovelSourcesListRef {
|
||||
_FetchNovelSourcesListProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
int? get id => (origin as FetchNovelSourcesListProvider).id;
|
||||
@override
|
||||
dynamic get reFresh => (origin as FetchNovelSourcesListProvider).reFresh;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
||||
Loading…
Reference in a new issue