add novel support

This commit is contained in:
playerterra1 2024-11-08 13:18:58 +00:00
parent 752387ccde
commit 34a451d374
23 changed files with 268 additions and 232 deletions

View file

@ -12,7 +12,8 @@ class History {
int? chapterId; int? chapterId;
ItemType? itemType; @enumerated
late ItemType itemType;
final chapter = IsarLink<Chapter>(); final chapter = IsarLink<Chapter>();

View file

@ -27,10 +27,11 @@ const HistorySchema = CollectionSchema(
name: r'date', name: r'date',
type: IsarType.string, type: IsarType.string,
), ),
r'isManga': PropertySchema( r'itemType': PropertySchema(
id: 2, id: 2,
name: r'isManga', name: r'itemType',
type: IsarType.bool, type: IsarType.byte,
enumMap: _HistoryitemTypeEnumValueMap,
), ),
r'mangaId': PropertySchema( r'mangaId': PropertySchema(
id: 3, id: 3,
@ -82,7 +83,7 @@ void _historySerialize(
) { ) {
writer.writeLong(offsets[0], object.chapterId); writer.writeLong(offsets[0], object.chapterId);
writer.writeString(offsets[1], object.date); writer.writeString(offsets[1], object.date);
writer.writeBool(offsets[2], object.isManga); writer.writeByte(offsets[2], object.itemType.index);
writer.writeLong(offsets[3], object.mangaId); writer.writeLong(offsets[3], object.mangaId);
} }
@ -96,7 +97,8 @@ History _historyDeserialize(
chapterId: reader.readLongOrNull(offsets[0]), chapterId: reader.readLongOrNull(offsets[0]),
date: reader.readStringOrNull(offsets[1]), date: reader.readStringOrNull(offsets[1]),
id: id, id: id,
isManga: reader.readBoolOrNull(offsets[2]), itemType: _HistoryitemTypeValueEnumMap[reader.readByteOrNull(offsets[2])] ??
ItemType.manga,
mangaId: reader.readLongOrNull(offsets[3]), mangaId: reader.readLongOrNull(offsets[3]),
); );
return object; return object;
@ -114,7 +116,8 @@ P _historyDeserializeProp<P>(
case 1: case 1:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 2: case 2:
return (reader.readBoolOrNull(offset)) as P; return (_HistoryitemTypeValueEnumMap[reader.readByteOrNull(offset)] ??
ItemType.manga) as P;
case 3: case 3:
return (reader.readLongOrNull(offset)) as P; return (reader.readLongOrNull(offset)) as P;
default: default:
@ -122,6 +125,17 @@ P _historyDeserializeProp<P>(
} }
} }
const _HistoryitemTypeEnumValueMap = {
'manga': 0,
'anime': 1,
'novel': 2,
};
const _HistoryitemTypeValueEnumMap = {
0: ItemType.manga,
1: ItemType.anime,
2: ItemType.novel,
};
Id _historyGetId(History object) { Id _historyGetId(History object) {
return object.id ?? Isar.autoIncrement; return object.id ?? Isar.autoIncrement;
} }
@ -495,32 +509,59 @@ extension HistoryQueryFilter
}); });
} }
QueryBuilder<History, History, QAfterFilterCondition> isMangaIsNull() { QueryBuilder<History, History, QAfterFilterCondition> itemTypeEqualTo(
return QueryBuilder.apply(this, (query) { ItemType value) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'isManga',
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> isMangaIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'isManga',
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> isMangaEqualTo(
bool? value) {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo( return query.addFilterCondition(FilterCondition.equalTo(
property: r'isManga', property: r'itemType',
value: value, value: value,
)); ));
}); });
} }
QueryBuilder<History, History, QAfterFilterCondition> itemTypeGreaterThan(
ItemType value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'itemType',
value: value,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> itemTypeLessThan(
ItemType value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'itemType',
value: value,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> itemTypeBetween(
ItemType lower,
ItemType upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'itemType',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> mangaIdIsNull() { QueryBuilder<History, History, QAfterFilterCondition> mangaIdIsNull() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull( return query.addFilterCondition(const FilterCondition.isNull(
@ -635,15 +676,15 @@ extension HistoryQuerySortBy on QueryBuilder<History, History, QSortBy> {
}); });
} }
QueryBuilder<History, History, QAfterSortBy> sortByIsManga() { QueryBuilder<History, History, QAfterSortBy> sortByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.asc); return query.addSortBy(r'itemType', Sort.asc);
}); });
} }
QueryBuilder<History, History, QAfterSortBy> sortByIsMangaDesc() { QueryBuilder<History, History, QAfterSortBy> sortByItemTypeDesc() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.desc); return query.addSortBy(r'itemType', Sort.desc);
}); });
} }
@ -698,15 +739,15 @@ extension HistoryQuerySortThenBy
}); });
} }
QueryBuilder<History, History, QAfterSortBy> thenByIsManga() { QueryBuilder<History, History, QAfterSortBy> thenByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.asc); return query.addSortBy(r'itemType', Sort.asc);
}); });
} }
QueryBuilder<History, History, QAfterSortBy> thenByIsMangaDesc() { QueryBuilder<History, History, QAfterSortBy> thenByItemTypeDesc() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.desc); return query.addSortBy(r'itemType', Sort.desc);
}); });
} }
@ -738,9 +779,9 @@ extension HistoryQueryWhereDistinct
}); });
} }
QueryBuilder<History, History, QDistinct> distinctByIsManga() { QueryBuilder<History, History, QDistinct> distinctByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'isManga'); return query.addDistinctBy(r'itemType');
}); });
} }
@ -771,9 +812,9 @@ extension HistoryQueryProperty
}); });
} }
QueryBuilder<History, bool?, QQueryOperations> isMangaProperty() { QueryBuilder<History, ItemType, QQueryOperations> itemTypeProperty() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'isManga'); return query.addPropertyName(r'itemType');
}); });
} }

View file

@ -72,49 +72,44 @@ const MangaSchema = CollectionSchema(
name: r'isLocalArchive', name: r'isLocalArchive',
type: IsarType.bool, type: IsarType.bool,
), ),
r'isManga': PropertySchema(
id: 11,
name: r'isManga',
type: IsarType.bool,
),
r'itemType': PropertySchema( r'itemType': PropertySchema(
id: 12, id: 11,
name: r'itemType', name: r'itemType',
type: IsarType.byte, type: IsarType.byte,
enumMap: _MangaitemTypeEnumValueMap, enumMap: _MangaitemTypeEnumValueMap,
), ),
r'lang': PropertySchema( r'lang': PropertySchema(
id: 13, id: 12,
name: r'lang', name: r'lang',
type: IsarType.string, type: IsarType.string,
), ),
r'lastRead': PropertySchema( r'lastRead': PropertySchema(
id: 14, id: 13,
name: r'lastRead', name: r'lastRead',
type: IsarType.long, type: IsarType.long,
), ),
r'lastUpdate': PropertySchema( r'lastUpdate': PropertySchema(
id: 15, id: 14,
name: r'lastUpdate', name: r'lastUpdate',
type: IsarType.long, type: IsarType.long,
), ),
r'link': PropertySchema( r'link': PropertySchema(
id: 16, id: 15,
name: r'link', name: r'link',
type: IsarType.string, type: IsarType.string,
), ),
r'name': PropertySchema( r'name': PropertySchema(
id: 17, id: 16,
name: r'name', name: r'name',
type: IsarType.string, type: IsarType.string,
), ),
r'source': PropertySchema( r'source': PropertySchema(
id: 18, id: 17,
name: r'source', name: r'source',
type: IsarType.string, type: IsarType.string,
), ),
r'status': PropertySchema( r'status': PropertySchema(
id: 19, id: 18,
name: r'status', name: r'status',
type: IsarType.byte, type: IsarType.byte,
enumMap: _MangastatusEnumValueMap, enumMap: _MangastatusEnumValueMap,
@ -246,15 +241,14 @@ void _mangaSerialize(
writer.writeStringList(offsets[8], object.genre); writer.writeStringList(offsets[8], object.genre);
writer.writeString(offsets[9], object.imageUrl); writer.writeString(offsets[9], object.imageUrl);
writer.writeBool(offsets[10], object.isLocalArchive); writer.writeBool(offsets[10], object.isLocalArchive);
writer.writeBool(offsets[11], object.isManga); writer.writeByte(offsets[11], object.itemType.index);
writer.writeByte(offsets[12], object.itemType.index); writer.writeString(offsets[12], object.lang);
writer.writeString(offsets[13], object.lang); writer.writeLong(offsets[13], object.lastRead);
writer.writeLong(offsets[14], object.lastRead); writer.writeLong(offsets[14], object.lastUpdate);
writer.writeLong(offsets[15], object.lastUpdate); writer.writeString(offsets[15], object.link);
writer.writeString(offsets[16], object.link); writer.writeString(offsets[16], object.name);
writer.writeString(offsets[17], object.name); writer.writeString(offsets[17], object.source);
writer.writeString(offsets[18], object.source); writer.writeByte(offsets[18], object.status.index);
writer.writeByte(offsets[19], object.status.index);
} }
Manga _mangaDeserialize( Manga _mangaDeserialize(
@ -276,16 +270,15 @@ Manga _mangaDeserialize(
id: id, id: id,
imageUrl: reader.readStringOrNull(offsets[9]), imageUrl: reader.readStringOrNull(offsets[9]),
isLocalArchive: reader.readBoolOrNull(offsets[10]), isLocalArchive: reader.readBoolOrNull(offsets[10]),
isManga: reader.readBoolOrNull(offsets[11]), itemType: _MangaitemTypeValueEnumMap[reader.readByteOrNull(offsets[11])] ??
itemType: _MangaitemTypeValueEnumMap[reader.readByteOrNull(offsets[12])] ??
ItemType.manga, ItemType.manga,
lang: reader.readStringOrNull(offsets[13]), lang: reader.readStringOrNull(offsets[12]),
lastRead: reader.readLongOrNull(offsets[14]), lastRead: reader.readLongOrNull(offsets[13]),
lastUpdate: reader.readLongOrNull(offsets[15]), lastUpdate: reader.readLongOrNull(offsets[14]),
link: reader.readStringOrNull(offsets[16]), link: reader.readStringOrNull(offsets[15]),
name: reader.readStringOrNull(offsets[17]), name: reader.readStringOrNull(offsets[16]),
source: reader.readStringOrNull(offsets[18]), source: reader.readStringOrNull(offsets[17]),
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[19])] ?? status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[18])] ??
Status.ongoing, Status.ongoing,
); );
return object; return object;
@ -321,23 +314,21 @@ P _mangaDeserializeProp<P>(
case 10: case 10:
return (reader.readBoolOrNull(offset)) as P; return (reader.readBoolOrNull(offset)) as P;
case 11: case 11:
return (reader.readBoolOrNull(offset)) as P;
case 12:
return (_MangaitemTypeValueEnumMap[reader.readByteOrNull(offset)] ?? return (_MangaitemTypeValueEnumMap[reader.readByteOrNull(offset)] ??
ItemType.manga) as P; ItemType.manga) as P;
case 13: case 12:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 13:
return (reader.readLongOrNull(offset)) as P;
case 14: case 14:
return (reader.readLongOrNull(offset)) as P; return (reader.readLongOrNull(offset)) as P;
case 15: case 15:
return (reader.readLongOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 16: case 16:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 17: case 17:
return (reader.readStringOrNull(offset)) as P; return (reader.readStringOrNull(offset)) as P;
case 18: case 18:
return (reader.readStringOrNull(offset)) as P;
case 19:
return (_MangastatusValueEnumMap[reader.readByteOrNull(offset)] ?? return (_MangastatusValueEnumMap[reader.readByteOrNull(offset)] ??
Status.ongoing) as P; Status.ongoing) as P;
default: default:
@ -1933,32 +1924,6 @@ extension MangaQueryFilter on QueryBuilder<Manga, Manga, QFilterCondition> {
}); });
} }
QueryBuilder<Manga, Manga, QAfterFilterCondition> isMangaIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'isManga',
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> isMangaIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'isManga',
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> isMangaEqualTo(
bool? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'isManga',
value: value,
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> itemTypeEqualTo( QueryBuilder<Manga, Manga, QAfterFilterCondition> itemTypeEqualTo(
ItemType value) { ItemType value) {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
@ -2938,18 +2903,6 @@ extension MangaQuerySortBy on QueryBuilder<Manga, Manga, QSortBy> {
}); });
} }
QueryBuilder<Manga, Manga, QAfterSortBy> sortByIsManga() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.asc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> sortByIsMangaDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.desc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> sortByItemType() { QueryBuilder<Manga, Manga, QAfterSortBy> sortByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'itemType', Sort.asc); return query.addSortBy(r'itemType', Sort.asc);
@ -3156,18 +3109,6 @@ extension MangaQuerySortThenBy on QueryBuilder<Manga, Manga, QSortThenBy> {
}); });
} }
QueryBuilder<Manga, Manga, QAfterSortBy> thenByIsManga() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.asc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> thenByIsMangaDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'isManga', Sort.desc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> thenByItemType() { QueryBuilder<Manga, Manga, QAfterSortBy> thenByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'itemType', Sort.asc); return query.addSortBy(r'itemType', Sort.asc);
@ -3338,12 +3279,6 @@ extension MangaQueryWhereDistinct on QueryBuilder<Manga, Manga, QDistinct> {
}); });
} }
QueryBuilder<Manga, Manga, QDistinct> distinctByIsManga() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'isManga');
});
}
QueryBuilder<Manga, Manga, QDistinct> distinctByItemType() { QueryBuilder<Manga, Manga, QDistinct> distinctByItemType() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'itemType'); return query.addDistinctBy(r'itemType');
@ -3471,12 +3406,6 @@ extension MangaQueryProperty on QueryBuilder<Manga, Manga, QQueryProperty> {
}); });
} }
QueryBuilder<Manga, bool?, QQueryOperations> isMangaProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'isManga');
});
}
QueryBuilder<Manga, ItemType, QQueryOperations> itemTypeProperty() { QueryBuilder<Manga, ItemType, QQueryOperations> itemTypeProperty() {
return QueryBuilder.apply(this, (query) { return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'itemType'); return query.addPropertyName(r'itemType');

View file

@ -7,7 +7,7 @@ part of 'anime_player_controller_provider.dart';
// ************************************************************************** // **************************************************************************
String _$animeStreamControllerHash() => String _$animeStreamControllerHash() =>
r'0d97207a4d015d5089766ccbeeba093c55cb1ef9'; r'd3ec7fe7ac2af84393b128e430fd2f5b9224ed14';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -119,10 +119,14 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen>
List<History> histories = isar.historys List<History> histories = isar.historys
.filter() .filter()
.idIsNotNull() .idIsNotNull()
.chapter((q) => q.manga((q) => .chapter((q) => q.manga((q) => q
q.isMangaEqualTo( .itemTypeEqualTo(_tabBarController
_tabBarController.index == .index ==
0))) 0
? ItemType.manga
: _tabBarController.index == 1
? ItemType.anime
: ItemType.novel)))
.findAllSync() .findAllSync()
.toList(); .toList();
isar.writeTxnSync(() { isar.writeTxnSync(() {
@ -150,6 +154,7 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen>
tabs: [ tabs: [
Tab(text: l10n.manga), Tab(text: l10n.manga),
Tab(text: l10n.anime), Tab(text: l10n.anime),
Tab(text: l10n.novel),
], ],
), ),
), ),
@ -157,11 +162,15 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen>
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
child: TabBarView(controller: _tabBarController, children: [ child: TabBarView(controller: _tabBarController, children: [
HistoryTab( HistoryTab(
isManga: true, itemType: ItemType.manga,
query: _textEditingController.text, query: _textEditingController.text,
), ),
HistoryTab( HistoryTab(
isManga: false, itemType: ItemType.anime,
query: _textEditingController.text,
),
HistoryTab(
itemType: ItemType.novel,
query: _textEditingController.text, query: _textEditingController.text,
) )
]), ]),
@ -173,8 +182,8 @@ class _HistoryScreenState extends ConsumerState<HistoryScreen>
class HistoryTab extends ConsumerStatefulWidget { class HistoryTab extends ConsumerStatefulWidget {
final String query; final String query;
final bool isManga; final ItemType itemType;
const HistoryTab({required this.isManga, required this.query, super.key}); const HistoryTab({required this.itemType, required this.query, super.key});
@override @override
ConsumerState<HistoryTab> createState() => _HistoryTabState(); ConsumerState<HistoryTab> createState() => _HistoryTabState();
@ -185,7 +194,7 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = l10nLocalizations(context)!; final l10n = l10nLocalizations(context)!;
final history = final history =
ref.watch(getAllHistoryStreamProvider(isManga: widget.isManga)); ref.watch(getAllHistoryStreamProvider(itemType: widget.itemType));
return Scaffold( return Scaffold(
body: history.when( body: history.when(
data: (data) { data: (data) {

View file

@ -9,22 +9,22 @@ part 'isar_providers.g.dart';
@riverpod @riverpod
Stream<List<History>> getAllHistoryStream(GetAllHistoryStreamRef ref, Stream<List<History>> getAllHistoryStream(GetAllHistoryStreamRef ref,
{required bool isManga}) async* { {required ItemType itemType}) async* {
yield* isar.historys yield* isar.historys
.filter() .filter()
.idIsNotNull() .idIsNotNull()
.and() .and()
.chapter((q) => q.manga((q) => q.isMangaEqualTo(isManga))) .chapter((q) => q.manga((q) => q.itemTypeEqualTo(itemType)))
.watch(fireImmediately: true); .watch(fireImmediately: true);
} }
@riverpod @riverpod
Stream<List<Update>> getAllUpdateStream(GetAllUpdateStreamRef ref, Stream<List<Update>> getAllUpdateStream(GetAllUpdateStreamRef ref,
{required bool isManga}) async* { {required ItemType itemType}) async* {
yield* isar.updates yield* isar.updates
.filter() .filter()
.idIsNotNull() .idIsNotNull()
.and() .and()
.chapter((q) => q.manga((q) => q.isMangaEqualTo(isManga))) .chapter((q) => q.manga((q) => q.itemTypeEqualTo(itemType)))
.watch(fireImmediately: true); .watch(fireImmediately: true);
} }

View file

@ -7,7 +7,7 @@ part of 'isar_providers.dart';
// ************************************************************************** // **************************************************************************
String _$getAllHistoryStreamHash() => String _$getAllHistoryStreamHash() =>
r'32dc5fa16315f199a5c86ee99cf59b7190c4d28e'; r'381b5515484ce36a197b91e7d5f17037177dd0f0';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {
@ -41,10 +41,10 @@ class GetAllHistoryStreamFamily extends Family<AsyncValue<List<History>>> {
/// See also [getAllHistoryStream]. /// See also [getAllHistoryStream].
GetAllHistoryStreamProvider call({ GetAllHistoryStreamProvider call({
required bool isManga, required ItemType itemType,
}) { }) {
return GetAllHistoryStreamProvider( return GetAllHistoryStreamProvider(
isManga: isManga, itemType: itemType,
); );
} }
@ -53,7 +53,7 @@ class GetAllHistoryStreamFamily extends Family<AsyncValue<List<History>>> {
covariant GetAllHistoryStreamProvider provider, covariant GetAllHistoryStreamProvider provider,
) { ) {
return call( return call(
isManga: provider.isManga, itemType: provider.itemType,
); );
} }
@ -77,11 +77,11 @@ class GetAllHistoryStreamProvider
extends AutoDisposeStreamProvider<List<History>> { extends AutoDisposeStreamProvider<List<History>> {
/// See also [getAllHistoryStream]. /// See also [getAllHistoryStream].
GetAllHistoryStreamProvider({ GetAllHistoryStreamProvider({
required bool isManga, required ItemType itemType,
}) : this._internal( }) : this._internal(
(ref) => getAllHistoryStream( (ref) => getAllHistoryStream(
ref as GetAllHistoryStreamRef, ref as GetAllHistoryStreamRef,
isManga: isManga, itemType: itemType,
), ),
from: getAllHistoryStreamProvider, from: getAllHistoryStreamProvider,
name: r'getAllHistoryStreamProvider', name: r'getAllHistoryStreamProvider',
@ -92,7 +92,7 @@ class GetAllHistoryStreamProvider
dependencies: GetAllHistoryStreamFamily._dependencies, dependencies: GetAllHistoryStreamFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
GetAllHistoryStreamFamily._allTransitiveDependencies, GetAllHistoryStreamFamily._allTransitiveDependencies,
isManga: isManga, itemType: itemType,
); );
GetAllHistoryStreamProvider._internal( GetAllHistoryStreamProvider._internal(
@ -102,10 +102,10 @@ class GetAllHistoryStreamProvider
required super.allTransitiveDependencies, required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash, required super.debugGetCreateSourceHash,
required super.from, required super.from,
required this.isManga, required this.itemType,
}) : super.internal(); }) : super.internal();
final bool isManga; final ItemType itemType;
@override @override
Override overrideWith( Override overrideWith(
@ -120,7 +120,7 @@ class GetAllHistoryStreamProvider
dependencies: null, dependencies: null,
allTransitiveDependencies: null, allTransitiveDependencies: null,
debugGetCreateSourceHash: null, debugGetCreateSourceHash: null,
isManga: isManga, itemType: itemType,
), ),
); );
} }
@ -132,21 +132,21 @@ class GetAllHistoryStreamProvider
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is GetAllHistoryStreamProvider && other.isManga == isManga; return other is GetAllHistoryStreamProvider && other.itemType == itemType;
} }
@override @override
int get hashCode { int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode); var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, isManga.hashCode); hash = _SystemHash.combine(hash, itemType.hashCode);
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
mixin GetAllHistoryStreamRef on AutoDisposeStreamProviderRef<List<History>> { mixin GetAllHistoryStreamRef on AutoDisposeStreamProviderRef<List<History>> {
/// The parameter `isManga` of this provider. /// The parameter `itemType` of this provider.
bool get isManga; ItemType get itemType;
} }
class _GetAllHistoryStreamProviderElement class _GetAllHistoryStreamProviderElement
@ -155,11 +155,11 @@ class _GetAllHistoryStreamProviderElement
_GetAllHistoryStreamProviderElement(super.provider); _GetAllHistoryStreamProviderElement(super.provider);
@override @override
bool get isManga => (origin as GetAllHistoryStreamProvider).isManga; ItemType get itemType => (origin as GetAllHistoryStreamProvider).itemType;
} }
String _$getAllUpdateStreamHash() => String _$getAllUpdateStreamHash() =>
r'9f62b36ef0b268ee8c3cc93a10f8963def8dfbb0'; r'44fb6b980fb11c51c4b6a6956104b02b7ae0a8ca';
/// See also [getAllUpdateStream]. /// See also [getAllUpdateStream].
@ProviderFor(getAllUpdateStream) @ProviderFor(getAllUpdateStream)
@ -172,10 +172,10 @@ class GetAllUpdateStreamFamily extends Family<AsyncValue<List<Update>>> {
/// See also [getAllUpdateStream]. /// See also [getAllUpdateStream].
GetAllUpdateStreamProvider call({ GetAllUpdateStreamProvider call({
required bool isManga, required ItemType itemType,
}) { }) {
return GetAllUpdateStreamProvider( return GetAllUpdateStreamProvider(
isManga: isManga, itemType: itemType,
); );
} }
@ -184,7 +184,7 @@ class GetAllUpdateStreamFamily extends Family<AsyncValue<List<Update>>> {
covariant GetAllUpdateStreamProvider provider, covariant GetAllUpdateStreamProvider provider,
) { ) {
return call( return call(
isManga: provider.isManga, itemType: provider.itemType,
); );
} }
@ -208,11 +208,11 @@ class GetAllUpdateStreamProvider
extends AutoDisposeStreamProvider<List<Update>> { extends AutoDisposeStreamProvider<List<Update>> {
/// See also [getAllUpdateStream]. /// See also [getAllUpdateStream].
GetAllUpdateStreamProvider({ GetAllUpdateStreamProvider({
required bool isManga, required ItemType itemType,
}) : this._internal( }) : this._internal(
(ref) => getAllUpdateStream( (ref) => getAllUpdateStream(
ref as GetAllUpdateStreamRef, ref as GetAllUpdateStreamRef,
isManga: isManga, itemType: itemType,
), ),
from: getAllUpdateStreamProvider, from: getAllUpdateStreamProvider,
name: r'getAllUpdateStreamProvider', name: r'getAllUpdateStreamProvider',
@ -223,7 +223,7 @@ class GetAllUpdateStreamProvider
dependencies: GetAllUpdateStreamFamily._dependencies, dependencies: GetAllUpdateStreamFamily._dependencies,
allTransitiveDependencies: allTransitiveDependencies:
GetAllUpdateStreamFamily._allTransitiveDependencies, GetAllUpdateStreamFamily._allTransitiveDependencies,
isManga: isManga, itemType: itemType,
); );
GetAllUpdateStreamProvider._internal( GetAllUpdateStreamProvider._internal(
@ -233,10 +233,10 @@ class GetAllUpdateStreamProvider
required super.allTransitiveDependencies, required super.allTransitiveDependencies,
required super.debugGetCreateSourceHash, required super.debugGetCreateSourceHash,
required super.from, required super.from,
required this.isManga, required this.itemType,
}) : super.internal(); }) : super.internal();
final bool isManga; final ItemType itemType;
@override @override
Override overrideWith( Override overrideWith(
@ -251,7 +251,7 @@ class GetAllUpdateStreamProvider
dependencies: null, dependencies: null,
allTransitiveDependencies: null, allTransitiveDependencies: null,
debugGetCreateSourceHash: null, debugGetCreateSourceHash: null,
isManga: isManga, itemType: itemType,
), ),
); );
} }
@ -263,21 +263,21 @@ class GetAllUpdateStreamProvider
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return other is GetAllUpdateStreamProvider && other.isManga == isManga; return other is GetAllUpdateStreamProvider && other.itemType == itemType;
} }
@override @override
int get hashCode { int get hashCode {
var hash = _SystemHash.combine(0, runtimeType.hashCode); var hash = _SystemHash.combine(0, runtimeType.hashCode);
hash = _SystemHash.combine(hash, isManga.hashCode); hash = _SystemHash.combine(hash, itemType.hashCode);
return _SystemHash.finish(hash); return _SystemHash.finish(hash);
} }
} }
mixin GetAllUpdateStreamRef on AutoDisposeStreamProviderRef<List<Update>> { mixin GetAllUpdateStreamRef on AutoDisposeStreamProviderRef<List<Update>> {
/// The parameter `isManga` of this provider. /// The parameter `itemType` of this provider.
bool get isManga; ItemType get itemType;
} }
class _GetAllUpdateStreamProviderElement class _GetAllUpdateStreamProviderElement
@ -286,7 +286,7 @@ class _GetAllUpdateStreamProviderElement
_GetAllUpdateStreamProviderElement(super.provider); _GetAllUpdateStreamProviderElement(super.provider);
@override @override
bool get isManga => (origin as GetAllUpdateStreamProvider).isManga; ItemType get itemType => (origin as GetAllUpdateStreamProvider).itemType;
} }
// ignore_for_file: type=lint // ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member // ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member

View file

@ -7,7 +7,7 @@ part of 'add_torrent.dart';
// ************************************************************************** // **************************************************************************
String _$addTorrentFromUrlOrFromFileHash() => String _$addTorrentFromUrlOrFromFileHash() =>
r'473a3494fd8c5089afdd460637f37faf2a498400'; r'06b057093b528b06714adbd984d07c5698c2830b';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -7,7 +7,7 @@ part of 'local_archive.dart';
// ************************************************************************** // **************************************************************************
String _$importArchivesFromFileHash() => String _$importArchivesFromFileHash() =>
r'08e34a4b0ba52b8d3861b297f687c1136f2c5443'; r'5d196054cc64e03d3efc2f5af098df5542776fec';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -20,10 +20,8 @@ Future<void> migration(MigrationRef ref) async {
.chapterIdIsNull() .chapterIdIsNull()
.or() .or()
.idIsNotNull() .idIsNotNull()
.isMangaIsNull()
.findAllSync(); .findAllSync();
final tracks = final tracks = isar.tracks.filter().idIsNotNull().findAllSync();
isar.tracks.filter().idIsNotNull().isMangaIsNull().findAllSync();
isar.writeTxnSync(() { isar.writeTxnSync(() {
//mangaId in chapter //mangaId in chapter
@ -39,15 +37,18 @@ Future<void> migration(MigrationRef ref) async {
//chapterId and isManga in History //chapterId and isManga in History
for (var history in histories) { for (var history in histories) {
final chapterId = history.chapter.value?.id; final chapterId = history.chapter.value?.id;
final itemType = history.chapter.value?.manga.value?.itemType; final itemType =
history.chapter.value?.manga.value?.itemType ?? ItemType.manga;
isar.historys.putSync(history isar.historys.putSync(history
..chapterId = chapterId ..chapterId = chapterId
..itemType = itemType); ..itemType = itemType);
} }
// isManga in Track // isManga in Track
for (var track in tracks) { for (var track in tracks) {
final itemType = isar.mangas.getSync(track.mangaId!)?.itemType; final isManga =
isar.tracks.putSync(track..itemType = itemType); (isar.mangas.getSync(track.mangaId!)?.itemType ?? ItemType.manga) ==
ItemType.manga;
isar.tracks.putSync(track..isManga = isManga);
} }
}); });
} }

View file

@ -6,7 +6,7 @@ part of 'migration.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$migrationHash() => r'6b3ff1b28168381079986d619b30c31ce44f341f'; String _$migrationHash() => r'8c5ba50ce563fc75a7185a99cb77759a8ef71964';
/// See also [migration]. /// See also [migration].
@ProviderFor(migration) @ProviderFor(migration)

View file

@ -511,7 +511,12 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (value == 0) { if (value == 0) {
context.push("/categories", extra: ( context.push("/categories", extra: (
true, true,
widget.manga!.isManga! ? 0 : 1 widget.manga!.itemType == ItemType.manga
? 0
: widget.manga!.itemType ==
ItemType.anime
? 1
: 2
)); ));
} else if (value == 1) { } else if (value == 1) {
} else if (value == 2) { } else if (value == 2) {
@ -585,7 +590,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
8), 8),
child: Text( child: Text(
widget.manga! widget.manga!
.isManga! .itemType !=
ItemType
.anime
? l10n.n_chapters( ? l10n.n_chapters(
chapters chapters
.length) .length)
@ -614,7 +621,10 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
color: context color: context
.secondaryColor), .secondaryColor),
label: Text( label: Text(
widget.manga!.isManga! widget.manga!
.itemType !=
ItemType
.anime
? l10n ? l10n
.add_chapters .add_chapters
: l10n : l10n
@ -1363,7 +1373,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
padding: padding:
const EdgeInsets.symmetric(horizontal: 8), const EdgeInsets.symmetric(horizontal: 8),
child: Text( child: Text(
widget.manga!.isManga! widget.manga!.itemType != ItemType.anime
? l10n.n_chapters(chapterLength) ? l10n.n_chapters(chapterLength)
: l10n.n_episodes(chapterLength), : l10n.n_episodes(chapterLength),
style: const TextStyle( style: const TextStyle(
@ -1380,7 +1390,7 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
icon: Icon(Icons.add, icon: Icon(Icons.add,
color: context.secondaryColor), color: context.secondaryColor),
label: Text( label: Text(
widget.manga!.isManga! widget.manga!.itemType != ItemType.anime
? l10n.add_chapters ? l10n.add_chapters
: l10n.add_episodes, : l10n.add_episodes,
style: TextStyle( style: TextStyle(
@ -1660,7 +1670,8 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
final trackSearch = final trackSearch =
await trackersSearchraggableMenu( await trackersSearchraggableMenu(
context, context,
isManga: widget.manga!.isManga!, isManga: widget.manga!.itemType !=
ItemType.anime,
track: Track( track: Track(
status: status:
TrackStatus.planToRead, TrackStatus.planToRead,
@ -1978,14 +1989,16 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
mangaId: widget.manga!.id!, mangaId: widget.manga!.id!,
syncId: entries[index].syncId!, syncId: entries[index].syncId!,
trackRes: trackRes.first, trackRes: trackRes.first,
isManga: widget.manga!.isManga!) isManga:
widget.manga!.itemType == ItemType.manga)
: TrackListile( : TrackListile(
text: l10nLocalizations(context)!.add_tracker, text: l10nLocalizations(context)!.add_tracker,
onTap: () async { onTap: () async {
final trackSearch = final trackSearch =
await trackersSearchraggableMenu( await trackersSearchraggableMenu(
context, context,
isManga: widget.manga!.isManga!, isManga: widget.manga!.itemType !=
ItemType.anime,
track: Track( track: Track(
status: TrackStatus.planToRead, status: TrackStatus.planToRead,
syncId: entries[index].syncId!, syncId: entries[index].syncId!,
@ -1995,7 +2008,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
await ref await ref
.read(trackStateProvider( .read(trackStateProvider(
track: null, track: null,
isManga: widget.manga!.isManga!) isManga:
widget.manga!.itemType !=
ItemType.anime)
.notifier) .notifier)
.setTrackSearch( .setTrackSearch(
trackSearch, trackSearch,

View file

@ -55,7 +55,7 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
.idIsNotNull() .idIsNotNull()
.and() .and()
.chapter((q) => q.manga( .chapter((q) => q.manga(
(q) => q.isMangaEqualTo(widget.manga.isManga!))) (q) => q.itemTypeEqualTo(widget.manga.itemType)))
.watch(fireImmediately: true), .watch(fireImmediately: true),
builder: (context, snapshot) { builder: (context, snapshot) {
final isFr = final isFr =
@ -294,8 +294,14 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
children: [ children: [
TextButton( TextButton(
onPressed: () { onPressed: () {
context.push("/categories", context.push("/categories", extra: (
extra: (true, widget.manga.isManga! ? 0 : 1)); true,
widget.manga.itemType == ItemType.manga
? 0
: widget.manga.itemType == ItemType.anime
? 1
: 2
));
Navigator.pop(context); Navigator.pop(context);
}, },
child: Text(l10n.edit)), child: Text(l10n.edit)),

View file

@ -48,7 +48,7 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link ..link = getManga.link?.trim().trimLeft().trimRight() ?? manga.link
..source = manga.source ..source = manga.source
..lang = manga.lang ..lang = manga.lang
..isManga = source.isManga ..itemType = source.itemType
..lastUpdate = DateTime.now().millisecondsSinceEpoch; ..lastUpdate = DateTime.now().millisecondsSinceEpoch;
final checkManga = isar.mangas.getSync(mangaId); final checkManga = isar.mangas.getSync(mangaId);
if (checkManga!.chapters.isNotEmpty && isInit) { if (checkManga!.chapters.isNotEmpty && isInit) {

View file

@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$updateMangaDetailHash() => r'736b68c65f624da85b15c0a7a2a263aab8e8df7e'; String _$updateMangaDetailHash() => r'dd2ea98fa3e4fc0c5fb9c0d3ba8334fe76e77249';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/models/chapter.dart'; import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/providers/l10n_providers.dart'; import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/date.dart'; import 'package:mangayomi/utils/date.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart'; import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -89,7 +90,7 @@ class ChapterListTileWidget extends ConsumerWidget {
children: [ children: [
const Text(''), const Text(''),
Text( Text(
!chapter.manga.value!.isManga! chapter.manga.value!.itemType == ItemType.anime
? l10n.episode_progress(Duration( ? l10n.episode_progress(Duration(
milliseconds: milliseconds:
int.parse(chapter.lastPageRead!)) int.parse(chapter.lastPageRead!))

View file

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/page.dart'; import 'package:mangayomi/models/page.dart';
import 'package:mangayomi/services/background_downloader/background_downloader.dart'; import 'package:mangayomi/services/background_downloader/background_downloader.dart';
import 'package:isar/isar.dart'; import 'package:isar/isar.dart';
@ -44,9 +45,15 @@ Future<List<PageUrl>> downloadChapter(
: ""; : "";
final chapterName = chapter.name!.replaceForbiddenCharacters(' '); final chapterName = chapter.name!.replaceForbiddenCharacters(' ');
final isManga = chapter.manga.value!.isManga!; final itemType = chapter.manga.value!.itemType;
final isManga = itemType == ItemType.manga;
final itemTypePath = itemType == ItemType.manga
? "Manga"
: itemType == ItemType.anime
? "Anime"
: "Novel";
final finalPath = final finalPath =
"downloads/${isManga ? "Manga" : "Anime"}/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}${isManga ? "/$scanlator${chapter.name!.replaceForbiddenCharacters('_')}" : ""}"; "downloads/$itemTypePath/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}${isManga ? "/$scanlator${chapter.name!.replaceForbiddenCharacters('_')}" : ""}";
path = Directory("${path1!.path}$finalPath/"); path = Directory("${path1!.path}$finalPath/");
Map<String, String> videoHeader = {}; Map<String, String> videoHeader = {};
bool hasM3U8File = false; bool hasM3U8File = false;

View file

@ -6,7 +6,7 @@ part of 'download_provider.dart';
// RiverpodGenerator // RiverpodGenerator
// ************************************************************************** // **************************************************************************
String _$downloadChapterHash() => r'ef2852f888f93e5f344241bc6b486c9dd9037251'; String _$downloadChapterHash() => r'3f66e451bd49afa53d57630d9f33ce98ab79bfd0';
/// Copied from Dart SDK /// Copied from Dart SDK
class _SystemHash { class _SystemHash {

View file

@ -5,6 +5,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:mangayomi/eval/dart/model/m_manga.dart'; import 'package:mangayomi/eval/dart/model/m_manga.dart';
import 'package:mangayomi/eval/dart/model/m_pages.dart'; import 'package:mangayomi/eval/dart/model/m_pages.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart'; import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart'; import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/library/providers/library_state_provider.dart'; import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
@ -548,7 +549,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
return buildProgressIndicator(); return buildProgressIndicator();
} }
return MangaHomeImageCardListTile( return MangaHomeImageCardListTile(
isManga: source.isManga ?? true, itemType: source.itemType,
manga: _mangaList[index], manga: _mangaList[index],
source: source); source: source);
}) })
@ -568,7 +569,7 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
return buildProgressIndicator(); return buildProgressIndicator();
} }
return MangaHomeImageCard( return MangaHomeImageCard(
isManga: source.isManga ?? true, itemType: source.itemType,
manga: _mangaList[index], manga: _mangaList[index],
source: source, source: source,
isComfortableGrid: isComfortableGrid, isComfortableGrid: isComfortableGrid,
@ -693,14 +694,14 @@ class _MangaHomeScreenState extends ConsumerState<MangaHomeScreen> {
class MangaHomeImageCard extends ConsumerStatefulWidget { class MangaHomeImageCard extends ConsumerStatefulWidget {
final MManga manga; final MManga manga;
final bool isManga; final ItemType itemType;
final Source source; final Source source;
final bool isComfortableGrid; final bool isComfortableGrid;
const MangaHomeImageCard( const MangaHomeImageCard(
{super.key, {super.key,
required this.manga, required this.manga,
required this.source, required this.source,
required this.isManga, required this.itemType,
required this.isComfortableGrid}); required this.isComfortableGrid});
@override @override
@ -716,7 +717,7 @@ class _MangaHomeImageCardState extends ConsumerState<MangaHomeImageCard>
return MangaImageCardWidget( return MangaImageCardWidget(
getMangaDetail: widget.manga, getMangaDetail: widget.manga,
source: widget.source, source: widget.source,
isManga: widget.isManga, itemType: widget.itemType,
isComfortableGrid: widget.isComfortableGrid); isComfortableGrid: widget.isComfortableGrid);
} }
@ -726,13 +727,13 @@ class _MangaHomeImageCardState extends ConsumerState<MangaHomeImageCard>
class MangaHomeImageCardListTile extends ConsumerStatefulWidget { class MangaHomeImageCardListTile extends ConsumerStatefulWidget {
final MManga manga; final MManga manga;
final bool isManga; final ItemType itemType;
final Source source; final Source source;
const MangaHomeImageCardListTile( const MangaHomeImageCardListTile(
{super.key, {super.key,
required this.manga, required this.manga,
required this.source, required this.source,
required this.isManga}); required this.itemType});
@override @override
ConsumerState<MangaHomeImageCardListTile> createState() => ConsumerState<MangaHomeImageCardListTile> createState() =>
@ -749,7 +750,7 @@ class _MangaHomeImageCardListTileState
return MangaImageCardListTileWidget( return MangaImageCardListTileWidget(
getMangaDetail: widget.manga, getMangaDetail: widget.manga,
source: widget.source, source: widget.source,
isManga: widget.isManga); itemType: widget.itemType);
} }
@override @override

View file

@ -169,7 +169,7 @@ class _CurrentIndexProviderElement
Chapter get chapter => (origin as CurrentIndexProvider).chapter; Chapter get chapter => (origin as CurrentIndexProvider).chapter;
} }
String _$readerControllerHash() => r'cc4f5fbe4192def4d19d9150340d305ba0ecf463'; String _$readerControllerHash() => r'6576f3506dc5ef309f870de3e5c6e92efe03eefd';
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> { abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
late final Chapter chapter; late final Chapter chapter;

View file

@ -48,6 +48,7 @@ class _CategoriesScreenState extends ConsumerState<CategoriesScreen>
tabs: [ tabs: [
Tab(text: l10n.manga), Tab(text: l10n.manga),
Tab(text: l10n.anime), Tab(text: l10n.anime),
Tab(text: l10n.novel),
], ],
), ),
), ),
@ -189,7 +190,8 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
.notifier) .notifier)
.addDeletedCategoryAsync( .addDeletedCategoryAsync(
_entries[ _entries[
index], false); index],
false);
await isar await isar
.categorys .categorys
.delete(_entries[ .delete(_entries[

View file

@ -42,7 +42,11 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
.idIsNotNull() .idIsNotNull()
.favoriteEqualTo(true) .favoriteEqualTo(true)
.and() .and()
.isMangaEqualTo(_tabBarController.index == 0) .itemTypeEqualTo(_tabBarController.index == 0
? ItemType.manga
: _tabBarController.index == 1
? ItemType.anime
: ItemType.novel)
.findAllSync(); .findAllSync();
int numbers = 0; int numbers = 0;
@ -160,10 +164,14 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
List<Update> updates = isar.updates List<Update> updates = isar.updates
.filter() .filter()
.idIsNotNull() .idIsNotNull()
.chapter((q) => q.manga((q) => .chapter((q) => q.manga((q) => q
q.isMangaEqualTo( .itemTypeEqualTo(_tabBarController
_tabBarController.index == .index ==
0))) 0
? ItemType.manga
: _tabBarController.index == 1
? ItemType.anime
: ItemType.novel)))
.findAllSync() .findAllSync()
.toList(); .toList();
isar.writeTxnSync(() { isar.writeTxnSync(() {
@ -191,6 +199,7 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
tabs: [ tabs: [
Tab(text: l10n.manga), Tab(text: l10n.manga),
Tab(text: l10n.anime), Tab(text: l10n.anime),
Tab(text: l10n.novel),
], ],
), ),
), ),
@ -198,11 +207,15 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
padding: const EdgeInsets.only(top: 10), padding: const EdgeInsets.only(top: 10),
child: TabBarView(controller: _tabBarController, children: [ child: TabBarView(controller: _tabBarController, children: [
UpdateTab( UpdateTab(
isManga: true, itemType: ItemType.manga,
query: _textEditingController.text, query: _textEditingController.text,
isLoading: _isLoading), isLoading: _isLoading),
UpdateTab( UpdateTab(
isManga: false, itemType: ItemType.anime,
query: _textEditingController.text,
isLoading: _isLoading),
UpdateTab(
itemType: ItemType.novel,
query: _textEditingController.text, query: _textEditingController.text,
isLoading: _isLoading) isLoading: _isLoading)
]), ]),
@ -214,10 +227,10 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
class UpdateTab extends ConsumerStatefulWidget { class UpdateTab extends ConsumerStatefulWidget {
final String query; final String query;
final bool isManga; final ItemType itemType;
final bool isLoading; final bool isLoading;
const UpdateTab( const UpdateTab(
{required this.isManga, {required this.itemType,
required this.query, required this.query,
required this.isLoading, required this.isLoading,
super.key}); super.key});
@ -231,7 +244,7 @@ class _UpdateTabState extends ConsumerState<UpdateTab> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = l10nLocalizations(context)!; final l10n = l10nLocalizations(context)!;
final update = final update =
ref.watch(getAllUpdateStreamProvider(isManga: widget.isManga)); ref.watch(getAllUpdateStreamProvider(itemType: widget.itemType));
return Scaffold( return Scaffold(
body: Stack( body: Stack(
children: [ children: [

View file

@ -83,18 +83,28 @@ class StorageProvider {
String scanlator = chapter.scanlator?.isNotEmpty ?? false String scanlator = chapter.scanlator?.isNotEmpty ?? false
? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_" ? "${chapter.scanlator!.replaceForbiddenCharacters('_')}_"
: ""; : "";
final isManga = chapter.manga.value!.isManga!; final itemType = chapter.manga.value!.itemType;
final itemTypePath = itemType == ItemType.manga
? "Manga"
: itemType == ItemType.anime
? "Anime"
: "Novel";
final dir = await getDirectory(); final dir = await getDirectory();
return Directory( return Directory(
"${dir!.path}/downloads/${isManga ? "Manga" : "Anime"}/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}/$scanlator${chapter.name!.replaceForbiddenCharacters('_')}/"); "${dir!.path}/downloads/$itemTypePath/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}/$scanlator${chapter.name!.replaceForbiddenCharacters('_')}/");
} }
Future<Directory?> getMangaMainDirectory(Chapter chapter) async { Future<Directory?> getMangaMainDirectory(Chapter chapter) async {
final manga = chapter.manga.value!; final manga = chapter.manga.value!;
final isManga = chapter.manga.value!.isManga!; final itemType = chapter.manga.value!.itemType;
final itemTypePath = itemType == ItemType.manga
? "Manga"
: itemType == ItemType.anime
? "Anime"
: "Novel";
final dir = await getDirectory(); final dir = await getDirectory();
return Directory( return Directory(
"${dir!.path}/downloads/${isManga ? "Manga" : "Anime"}/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}/"); "${dir!.path}/downloads/$itemTypePath/${manga.source} (${manga.lang!.toUpperCase()})/${manga.name!.replaceForbiddenCharacters('_')}/");
} }
Future<Directory?> getDatabaseDirectory() async { Future<Directory?> getDatabaseDirectory() async {