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;
ItemType? itemType;
@enumerated
late ItemType itemType;
final chapter = IsarLink<Chapter>();

View file

@ -27,10 +27,11 @@ const HistorySchema = CollectionSchema(
name: r'date',
type: IsarType.string,
),
r'isManga': PropertySchema(
r'itemType': PropertySchema(
id: 2,
name: r'isManga',
type: IsarType.bool,
name: r'itemType',
type: IsarType.byte,
enumMap: _HistoryitemTypeEnumValueMap,
),
r'mangaId': PropertySchema(
id: 3,
@ -82,7 +83,7 @@ void _historySerialize(
) {
writer.writeLong(offsets[0], object.chapterId);
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);
}
@ -96,7 +97,8 @@ History _historyDeserialize(
chapterId: reader.readLongOrNull(offsets[0]),
date: reader.readStringOrNull(offsets[1]),
id: id,
isManga: reader.readBoolOrNull(offsets[2]),
itemType: _HistoryitemTypeValueEnumMap[reader.readByteOrNull(offsets[2])] ??
ItemType.manga,
mangaId: reader.readLongOrNull(offsets[3]),
);
return object;
@ -114,7 +116,8 @@ P _historyDeserializeProp<P>(
case 1:
return (reader.readStringOrNull(offset)) as P;
case 2:
return (reader.readBoolOrNull(offset)) as P;
return (_HistoryitemTypeValueEnumMap[reader.readByteOrNull(offset)] ??
ItemType.manga) as P;
case 3:
return (reader.readLongOrNull(offset)) as P;
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) {
return object.id ?? Isar.autoIncrement;
}
@ -495,32 +509,59 @@ extension HistoryQueryFilter
});
}
QueryBuilder<History, History, QAfterFilterCondition> isMangaIsNull() {
return QueryBuilder.apply(this, (query) {
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) {
QueryBuilder<History, History, QAfterFilterCondition> itemTypeEqualTo(
ItemType value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'isManga',
property: r'itemType',
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() {
return QueryBuilder.apply(this, (query) {
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 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 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 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 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 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 query.addPropertyName(r'isManga');
return query.addPropertyName(r'itemType');
});
}

View file

@ -72,49 +72,44 @@ const MangaSchema = CollectionSchema(
name: r'isLocalArchive',
type: IsarType.bool,
),
r'isManga': PropertySchema(
id: 11,
name: r'isManga',
type: IsarType.bool,
),
r'itemType': PropertySchema(
id: 12,
id: 11,
name: r'itemType',
type: IsarType.byte,
enumMap: _MangaitemTypeEnumValueMap,
),
r'lang': PropertySchema(
id: 13,
id: 12,
name: r'lang',
type: IsarType.string,
),
r'lastRead': PropertySchema(
id: 14,
id: 13,
name: r'lastRead',
type: IsarType.long,
),
r'lastUpdate': PropertySchema(
id: 15,
id: 14,
name: r'lastUpdate',
type: IsarType.long,
),
r'link': PropertySchema(
id: 16,
id: 15,
name: r'link',
type: IsarType.string,
),
r'name': PropertySchema(
id: 17,
id: 16,
name: r'name',
type: IsarType.string,
),
r'source': PropertySchema(
id: 18,
id: 17,
name: r'source',
type: IsarType.string,
),
r'status': PropertySchema(
id: 19,
id: 18,
name: r'status',
type: IsarType.byte,
enumMap: _MangastatusEnumValueMap,
@ -246,15 +241,14 @@ void _mangaSerialize(
writer.writeStringList(offsets[8], object.genre);
writer.writeString(offsets[9], object.imageUrl);
writer.writeBool(offsets[10], object.isLocalArchive);
writer.writeBool(offsets[11], object.isManga);
writer.writeByte(offsets[12], object.itemType.index);
writer.writeString(offsets[13], object.lang);
writer.writeLong(offsets[14], object.lastRead);
writer.writeLong(offsets[15], object.lastUpdate);
writer.writeString(offsets[16], object.link);
writer.writeString(offsets[17], object.name);
writer.writeString(offsets[18], object.source);
writer.writeByte(offsets[19], object.status.index);
writer.writeByte(offsets[11], object.itemType.index);
writer.writeString(offsets[12], object.lang);
writer.writeLong(offsets[13], object.lastRead);
writer.writeLong(offsets[14], object.lastUpdate);
writer.writeString(offsets[15], object.link);
writer.writeString(offsets[16], object.name);
writer.writeString(offsets[17], object.source);
writer.writeByte(offsets[18], object.status.index);
}
Manga _mangaDeserialize(
@ -276,16 +270,15 @@ Manga _mangaDeserialize(
id: id,
imageUrl: reader.readStringOrNull(offsets[9]),
isLocalArchive: reader.readBoolOrNull(offsets[10]),
isManga: reader.readBoolOrNull(offsets[11]),
itemType: _MangaitemTypeValueEnumMap[reader.readByteOrNull(offsets[12])] ??
itemType: _MangaitemTypeValueEnumMap[reader.readByteOrNull(offsets[11])] ??
ItemType.manga,
lang: reader.readStringOrNull(offsets[13]),
lastRead: reader.readLongOrNull(offsets[14]),
lastUpdate: reader.readLongOrNull(offsets[15]),
link: reader.readStringOrNull(offsets[16]),
name: reader.readStringOrNull(offsets[17]),
source: reader.readStringOrNull(offsets[18]),
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[19])] ??
lang: reader.readStringOrNull(offsets[12]),
lastRead: reader.readLongOrNull(offsets[13]),
lastUpdate: reader.readLongOrNull(offsets[14]),
link: reader.readStringOrNull(offsets[15]),
name: reader.readStringOrNull(offsets[16]),
source: reader.readStringOrNull(offsets[17]),
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[18])] ??
Status.ongoing,
);
return object;
@ -321,23 +314,21 @@ P _mangaDeserializeProp<P>(
case 10:
return (reader.readBoolOrNull(offset)) as P;
case 11:
return (reader.readBoolOrNull(offset)) as P;
case 12:
return (_MangaitemTypeValueEnumMap[reader.readByteOrNull(offset)] ??
ItemType.manga) as P;
case 13:
case 12:
return (reader.readStringOrNull(offset)) as P;
case 13:
return (reader.readLongOrNull(offset)) as P;
case 14:
return (reader.readLongOrNull(offset)) as P;
case 15:
return (reader.readLongOrNull(offset)) as P;
return (reader.readStringOrNull(offset)) as P;
case 16:
return (reader.readStringOrNull(offset)) as P;
case 17:
return (reader.readStringOrNull(offset)) as P;
case 18:
return (reader.readStringOrNull(offset)) as P;
case 19:
return (_MangastatusValueEnumMap[reader.readByteOrNull(offset)] ??
Status.ongoing) as P;
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(
ItemType value) {
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() {
return QueryBuilder.apply(this, (query) {
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() {
return QueryBuilder.apply(this, (query) {
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() {
return QueryBuilder.apply(this, (query) {
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() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'itemType');

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -20,10 +20,8 @@ Future<void> migration(MigrationRef ref) async {
.chapterIdIsNull()
.or()
.idIsNotNull()
.isMangaIsNull()
.findAllSync();
final tracks =
isar.tracks.filter().idIsNotNull().isMangaIsNull().findAllSync();
final tracks = isar.tracks.filter().idIsNotNull().findAllSync();
isar.writeTxnSync(() {
//mangaId in chapter
@ -39,15 +37,18 @@ Future<void> migration(MigrationRef ref) async {
//chapterId and isManga in History
for (var history in histories) {
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
..chapterId = chapterId
..itemType = itemType);
}
// isManga in Track
for (var track in tracks) {
final itemType = isar.mangas.getSync(track.mangaId!)?.itemType;
isar.tracks.putSync(track..itemType = itemType);
final isManga =
(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
// **************************************************************************
String _$migrationHash() => r'6b3ff1b28168381079986d619b30c31ce44f341f';
String _$migrationHash() => r'8c5ba50ce563fc75a7185a99cb77759a8ef71964';
/// See also [migration].
@ProviderFor(migration)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/page.dart';
import 'package:mangayomi/services/background_downloader/background_downloader.dart';
import 'package:isar/isar.dart';
@ -44,9 +45,15 @@ Future<List<PageUrl>> downloadChapter(
: "";
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 =
"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/");
Map<String, String> videoHeader = {};
bool hasM3U8File = false;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -83,18 +83,28 @@ class StorageProvider {
String scanlator = chapter.scanlator?.isNotEmpty ?? false
? "${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();
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 {
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();
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 {