rename feed to update and make some arrangements
This commit is contained in:
parent
bb1423969d
commit
ee9e2a76cb
18 changed files with 663 additions and 637 deletions
|
|
@ -3,7 +3,6 @@
|
|||
"library": "Library",
|
||||
"updates": "Updates",
|
||||
"history": "History",
|
||||
"feed": "Feed",
|
||||
"browse": "Browse",
|
||||
"more": "More",
|
||||
"open_random_entry": "Open random entry",
|
||||
|
|
@ -40,7 +39,7 @@
|
|||
"no_recent_updates": "No recent updates",
|
||||
"remove_everything": "Remove everything",
|
||||
"remove_everything_msg": "Are you sure? All history will be lost",
|
||||
"remove_all_feed_msg": "Are you sure? The whole feed will be cleared",
|
||||
"remove_all_update_msg": "Are you sure? The whole update will be cleared",
|
||||
"ok": "OK",
|
||||
"cancel": "Cancel",
|
||||
"remove": "Remove",
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
part 'feed.g.dart';
|
||||
part 'update.g.dart';
|
||||
|
||||
@collection
|
||||
@Name("Feed")
|
||||
class Feed {
|
||||
@Name("Update")
|
||||
class Update {
|
||||
Id? id;
|
||||
|
||||
int? mangaId;
|
||||
|
|
@ -15,14 +15,14 @@ class Feed {
|
|||
|
||||
String? date;
|
||||
|
||||
Feed({
|
||||
Update({
|
||||
this.id = Isar.autoIncrement,
|
||||
required this.mangaId,
|
||||
required this.chapterName,
|
||||
required this.date,
|
||||
});
|
||||
|
||||
Feed.fromJson(Map<String, dynamic> json) {
|
||||
Update.fromJson(Map<String, dynamic> json) {
|
||||
id = json['id'];
|
||||
mangaId = json['mangaId'];
|
||||
chapterName = json['chapterName'];
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'feed.dart';
|
||||
part of 'update.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// IsarCollectionGenerator
|
||||
|
|
@ -9,13 +9,13 @@ part of 'feed.dart';
|
|||
// coverage:ignore-file
|
||||
// ignore_for_file: duplicate_ignore, non_constant_identifier_names, constant_identifier_names, invalid_use_of_protected_member, unnecessary_cast, prefer_const_constructors, lines_longer_than_80_chars, require_trailing_commas, inference_failure_on_function_invocation, unnecessary_parenthesis, unnecessary_raw_strings, unnecessary_null_checks, join_return_with_assignment, prefer_final_locals, avoid_js_rounded_ints, avoid_positional_boolean_parameters, always_specify_types
|
||||
|
||||
extension GetFeedCollection on Isar {
|
||||
IsarCollection<Feed> get feeds => this.collection();
|
||||
extension GetUpdateCollection on Isar {
|
||||
IsarCollection<Update> get updates => this.collection();
|
||||
}
|
||||
|
||||
const FeedSchema = CollectionSchema(
|
||||
name: r'Feed',
|
||||
id: 8879644747771893978,
|
||||
const UpdateSchema = CollectionSchema(
|
||||
name: r'Update',
|
||||
id: -8192355249181452821,
|
||||
properties: {
|
||||
r'chapterName': PropertySchema(
|
||||
id: 0,
|
||||
|
|
@ -33,29 +33,29 @@ const FeedSchema = CollectionSchema(
|
|||
type: IsarType.long,
|
||||
)
|
||||
},
|
||||
estimateSize: _feedEstimateSize,
|
||||
serialize: _feedSerialize,
|
||||
deserialize: _feedDeserialize,
|
||||
deserializeProp: _feedDeserializeProp,
|
||||
estimateSize: _updateEstimateSize,
|
||||
serialize: _updateSerialize,
|
||||
deserialize: _updateDeserialize,
|
||||
deserializeProp: _updateDeserializeProp,
|
||||
idName: r'id',
|
||||
indexes: {},
|
||||
links: {
|
||||
r'chapter': LinkSchema(
|
||||
id: 8037684855892205613,
|
||||
id: -7524967726288995715,
|
||||
name: r'chapter',
|
||||
target: r'Chapter',
|
||||
single: true,
|
||||
)
|
||||
},
|
||||
embeddedSchemas: {},
|
||||
getId: _feedGetId,
|
||||
getLinks: _feedGetLinks,
|
||||
attach: _feedAttach,
|
||||
getId: _updateGetId,
|
||||
getLinks: _updateGetLinks,
|
||||
attach: _updateAttach,
|
||||
version: '3.1.0+1',
|
||||
);
|
||||
|
||||
int _feedEstimateSize(
|
||||
Feed object,
|
||||
int _updateEstimateSize(
|
||||
Update object,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {
|
||||
|
|
@ -75,8 +75,8 @@ int _feedEstimateSize(
|
|||
return bytesCount;
|
||||
}
|
||||
|
||||
void _feedSerialize(
|
||||
Feed object,
|
||||
void _updateSerialize(
|
||||
Update object,
|
||||
IsarWriter writer,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
|
|
@ -86,13 +86,13 @@ void _feedSerialize(
|
|||
writer.writeLong(offsets[2], object.mangaId);
|
||||
}
|
||||
|
||||
Feed _feedDeserialize(
|
||||
Update _updateDeserialize(
|
||||
Id id,
|
||||
IsarReader reader,
|
||||
List<int> offsets,
|
||||
Map<Type, List<int>> allOffsets,
|
||||
) {
|
||||
final object = Feed(
|
||||
final object = Update(
|
||||
chapterName: reader.readStringOrNull(offsets[0]),
|
||||
date: reader.readStringOrNull(offsets[1]),
|
||||
id: id,
|
||||
|
|
@ -101,7 +101,7 @@ Feed _feedDeserialize(
|
|||
return object;
|
||||
}
|
||||
|
||||
P _feedDeserializeProp<P>(
|
||||
P _updateDeserializeProp<P>(
|
||||
IsarReader reader,
|
||||
int propertyId,
|
||||
int offset,
|
||||
|
|
@ -119,29 +119,29 @@ P _feedDeserializeProp<P>(
|
|||
}
|
||||
}
|
||||
|
||||
Id _feedGetId(Feed object) {
|
||||
Id _updateGetId(Update object) {
|
||||
return object.id ?? Isar.autoIncrement;
|
||||
}
|
||||
|
||||
List<IsarLinkBase<dynamic>> _feedGetLinks(Feed object) {
|
||||
List<IsarLinkBase<dynamic>> _updateGetLinks(Update object) {
|
||||
return [object.chapter];
|
||||
}
|
||||
|
||||
void _feedAttach(IsarCollection<dynamic> col, Id id, Feed object) {
|
||||
void _updateAttach(IsarCollection<dynamic> col, Id id, Update object) {
|
||||
object.id = id;
|
||||
object.chapter.attach(col, col.isar.collection<Chapter>(), r'chapter', id);
|
||||
}
|
||||
|
||||
extension FeedQueryWhereSort on QueryBuilder<Feed, Feed, QWhere> {
|
||||
QueryBuilder<Feed, Feed, QAfterWhere> anyId() {
|
||||
extension UpdateQueryWhereSort on QueryBuilder<Update, Update, QWhere> {
|
||||
QueryBuilder<Update, Update, QAfterWhere> anyId() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(const IdWhereClause.any());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
||||
QueryBuilder<Feed, Feed, QAfterWhereClause> idEqualTo(Id id) {
|
||||
extension UpdateQueryWhere on QueryBuilder<Update, Update, QWhereClause> {
|
||||
QueryBuilder<Update, Update, QAfterWhereClause> idEqualTo(Id id) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(IdWhereClause.between(
|
||||
lower: id,
|
||||
|
|
@ -150,7 +150,7 @@ extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterWhereClause> idNotEqualTo(Id id) {
|
||||
QueryBuilder<Update, Update, QAfterWhereClause> idNotEqualTo(Id id) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
if (query.whereSort == Sort.asc) {
|
||||
return query
|
||||
|
|
@ -172,7 +172,7 @@ extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterWhereClause> idGreaterThan(Id id,
|
||||
QueryBuilder<Update, Update, QAfterWhereClause> idGreaterThan(Id id,
|
||||
{bool include = false}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(
|
||||
|
|
@ -181,7 +181,7 @@ extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterWhereClause> idLessThan(Id id,
|
||||
QueryBuilder<Update, Update, QAfterWhereClause> idLessThan(Id id,
|
||||
{bool include = false}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addWhereClause(
|
||||
|
|
@ -190,7 +190,7 @@ extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterWhereClause> idBetween(
|
||||
QueryBuilder<Update, Update, QAfterWhereClause> idBetween(
|
||||
Id lowerId,
|
||||
Id upperId, {
|
||||
bool includeLower = true,
|
||||
|
|
@ -207,8 +207,8 @@ extension FeedQueryWhere on QueryBuilder<Feed, Feed, QWhereClause> {
|
|||
}
|
||||
}
|
||||
|
||||
extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameIsNull() {
|
||||
extension UpdateQueryFilter on QueryBuilder<Update, Update, QFilterCondition> {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'chapterName',
|
||||
|
|
@ -216,7 +216,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameIsNotNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'chapterName',
|
||||
|
|
@ -224,7 +224,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameEqualTo(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -237,7 +237,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameGreaterThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameGreaterThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
|
|
@ -252,7 +252,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameLessThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameLessThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
|
|
@ -267,7 +267,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameBetween(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool includeLower = true,
|
||||
|
|
@ -286,7 +286,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameStartsWith(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -299,7 +299,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameEndsWith(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -312,7 +312,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameContains(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameContains(
|
||||
String value,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -324,7 +324,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameMatches(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameMatches(
|
||||
String pattern,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -336,7 +336,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameIsEmpty() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'chapterName',
|
||||
|
|
@ -345,7 +345,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterNameIsNotEmpty() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterNameIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'chapterName',
|
||||
|
|
@ -354,7 +354,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateIsNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'date',
|
||||
|
|
@ -362,7 +362,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateIsNotNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'date',
|
||||
|
|
@ -370,7 +370,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateEqualTo(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -383,7 +383,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateGreaterThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateGreaterThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
|
|
@ -398,7 +398,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateLessThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateLessThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
|
|
@ -413,7 +413,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateBetween(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool includeLower = true,
|
||||
|
|
@ -432,7 +432,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateStartsWith(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -445,7 +445,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateEndsWith(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
|
|
@ -458,7 +458,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateContains(String value,
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateContains(String value,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.contains(
|
||||
|
|
@ -469,7 +469,8 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateMatches(String pattern,
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateMatches(
|
||||
String pattern,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.matches(
|
||||
|
|
@ -480,7 +481,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateIsEmpty() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'date',
|
||||
|
|
@ -489,7 +490,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> dateIsNotEmpty() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> dateIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'date',
|
||||
|
|
@ -498,7 +499,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idIsNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'id',
|
||||
|
|
@ -506,7 +507,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idIsNotNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'id',
|
||||
|
|
@ -514,7 +515,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idEqualTo(Id? value) {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idEqualTo(Id? value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'id',
|
||||
|
|
@ -523,7 +524,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idGreaterThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idGreaterThan(
|
||||
Id? value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
|
|
@ -536,7 +537,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idLessThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idLessThan(
|
||||
Id? value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
|
|
@ -549,7 +550,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> idBetween(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> idBetween(
|
||||
Id? lower,
|
||||
Id? upper, {
|
||||
bool includeLower = true,
|
||||
|
|
@ -566,7 +567,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdIsNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'mangaId',
|
||||
|
|
@ -574,7 +575,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdIsNotNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'mangaId',
|
||||
|
|
@ -582,7 +583,8 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdEqualTo(int? value) {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdEqualTo(
|
||||
int? value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'mangaId',
|
||||
|
|
@ -591,7 +593,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdGreaterThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdGreaterThan(
|
||||
int? value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
|
|
@ -604,7 +606,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdLessThan(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdLessThan(
|
||||
int? value, {
|
||||
bool include = false,
|
||||
}) {
|
||||
|
|
@ -617,7 +619,7 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> mangaIdBetween(
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> mangaIdBetween(
|
||||
int? lower,
|
||||
int? upper, {
|
||||
bool includeLower = true,
|
||||
|
|
@ -635,153 +637,153 @@ extension FeedQueryFilter on QueryBuilder<Feed, Feed, QFilterCondition> {
|
|||
}
|
||||
}
|
||||
|
||||
extension FeedQueryObject on QueryBuilder<Feed, Feed, QFilterCondition> {}
|
||||
extension UpdateQueryObject on QueryBuilder<Update, Update, QFilterCondition> {}
|
||||
|
||||
extension FeedQueryLinks on QueryBuilder<Feed, Feed, QFilterCondition> {
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapter(
|
||||
extension UpdateQueryLinks on QueryBuilder<Update, Update, QFilterCondition> {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapter(
|
||||
FilterQuery<Chapter> q) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.link(q, r'chapter');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterFilterCondition> chapterIsNull() {
|
||||
QueryBuilder<Update, Update, QAfterFilterCondition> chapterIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.linkLength(r'chapter', 0, true, 0, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedQuerySortBy on QueryBuilder<Feed, Feed, QSortBy> {
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByChapterName() {
|
||||
extension UpdateQuerySortBy on QueryBuilder<Update, Update, QSortBy> {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByChapterName() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'chapterName', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByChapterNameDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByChapterNameDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'chapterName', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByDate() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByDate() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'date', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByDateDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByDateDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'date', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByMangaId() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByMangaId() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'mangaId', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> sortByMangaIdDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> sortByMangaIdDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'mangaId', Sort.desc);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedQuerySortThenBy on QueryBuilder<Feed, Feed, QSortThenBy> {
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByChapterName() {
|
||||
extension UpdateQuerySortThenBy on QueryBuilder<Update, Update, QSortThenBy> {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByChapterName() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'chapterName', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByChapterNameDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByChapterNameDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'chapterName', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByDate() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByDate() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'date', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByDateDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByDateDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'date', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenById() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenById() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'id', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByIdDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByIdDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'id', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByMangaId() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByMangaId() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'mangaId', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QAfterSortBy> thenByMangaIdDesc() {
|
||||
QueryBuilder<Update, Update, QAfterSortBy> thenByMangaIdDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'mangaId', Sort.desc);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedQueryWhereDistinct on QueryBuilder<Feed, Feed, QDistinct> {
|
||||
QueryBuilder<Feed, Feed, QDistinct> distinctByChapterName(
|
||||
extension UpdateQueryWhereDistinct on QueryBuilder<Update, Update, QDistinct> {
|
||||
QueryBuilder<Update, Update, QDistinct> distinctByChapterName(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'chapterName', caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QDistinct> distinctByDate(
|
||||
QueryBuilder<Update, Update, QDistinct> distinctByDate(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'date', caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, Feed, QDistinct> distinctByMangaId() {
|
||||
QueryBuilder<Update, Update, QDistinct> distinctByMangaId() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'mangaId');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
extension FeedQueryProperty on QueryBuilder<Feed, Feed, QQueryProperty> {
|
||||
QueryBuilder<Feed, int, QQueryOperations> idProperty() {
|
||||
extension UpdateQueryProperty on QueryBuilder<Update, Update, QQueryProperty> {
|
||||
QueryBuilder<Update, int, QQueryOperations> idProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'id');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, String?, QQueryOperations> chapterNameProperty() {
|
||||
QueryBuilder<Update, String?, QQueryOperations> chapterNameProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'chapterName');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, String?, QQueryOperations> dateProperty() {
|
||||
QueryBuilder<Update, String?, QQueryOperations> dateProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'date');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Feed, int?, QQueryOperations> mangaIdProperty() {
|
||||
QueryBuilder<Update, int?, QQueryOperations> mangaIdProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'mangaId');
|
||||
});
|
||||
|
|
@ -1,262 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
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/chapter.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/feed/widgets/feed_chapter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
import 'package:mangayomi/modules/widgets/error_text.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
class FeedScreen extends ConsumerStatefulWidget {
|
||||
const FeedScreen({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<FeedScreen> createState() => _FeedScreenState();
|
||||
}
|
||||
|
||||
class _FeedScreenState extends ConsumerState<FeedScreen>
|
||||
with TickerProviderStateMixin {
|
||||
late TabController _tabBarController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_tabBarController = TabController(length: 2, vsync: this);
|
||||
_tabBarController.animateTo(0);
|
||||
_tabBarController.addListener(() {
|
||||
setState(() {
|
||||
_textEditingController.clear();
|
||||
_isSearch = false;
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
final _textEditingController = TextEditingController();
|
||||
bool _isSearch = false;
|
||||
List<History> entriesData = [];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return DefaultTabController(
|
||||
animationDuration: Duration.zero,
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: _isSearch
|
||||
? null
|
||||
: Text(
|
||||
l10n.feed,
|
||||
style: TextStyle(color: Theme.of(context).hintColor),
|
||||
),
|
||||
actions: [
|
||||
_isSearch
|
||||
? SeachFormTextField(
|
||||
onChanged: (value) {
|
||||
setState(() {});
|
||||
},
|
||||
onSuffixPressed: () {
|
||||
_textEditingController.clear();
|
||||
setState(() {});
|
||||
},
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = false;
|
||||
});
|
||||
_textEditingController.clear();
|
||||
},
|
||||
controller: _textEditingController,
|
||||
)
|
||||
: IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = true;
|
||||
});
|
||||
},
|
||||
icon:
|
||||
Icon(Icons.search, color: Theme.of(context).hintColor)),
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
l10n.remove_everything,
|
||||
),
|
||||
content: Text(l10n.remove_all_feed_msg),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel)),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
List<Feed> feeds = isar.feeds
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.chapter((q) => q.manga((q) =>
|
||||
q.isMangaEqualTo(
|
||||
_tabBarController.index ==
|
||||
0)))
|
||||
.findAllSync()
|
||||
.toList();
|
||||
isar.writeTxnSync(() {
|
||||
for (var feed in feeds) {
|
||||
isar.feeds.deleteSync(feed.id!);
|
||||
}
|
||||
});
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.ok)),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.delete_sweep_outlined,
|
||||
color: Theme.of(context).hintColor)),
|
||||
],
|
||||
bottom: TabBar(
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
controller: _tabBarController,
|
||||
tabs: [
|
||||
Tab(text: l10n.manga),
|
||||
Tab(text: l10n.anime),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: TabBarView(controller: _tabBarController, children: [
|
||||
FeedTab(
|
||||
isManga: true,
|
||||
query: _textEditingController.text,
|
||||
),
|
||||
FeedTab(
|
||||
isManga: false,
|
||||
query: _textEditingController.text,
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FeedTab extends ConsumerStatefulWidget {
|
||||
final String query;
|
||||
final bool isManga;
|
||||
const FeedTab({required this.isManga, required this.query, super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<FeedTab> createState() => _FeedTabState();
|
||||
}
|
||||
|
||||
class _FeedTabState extends ConsumerState<FeedTab> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final feed = ref.watch(getAllFeedStreamProvider(isManga: widget.isManga));
|
||||
return Scaffold(
|
||||
body: feed.when(
|
||||
data: (data) {
|
||||
final entries = data
|
||||
.where((element) => widget.query.isNotEmpty
|
||||
? element.chapter.value!.manga.value!.name!
|
||||
.toLowerCase()
|
||||
.contains(widget.query.toLowerCase())
|
||||
: true)
|
||||
.toList();
|
||||
final lastUpdatedList =
|
||||
data.map((e) => e.chapter.value!.manga.value!.lastUpdate!).toList();
|
||||
lastUpdatedList.sort((a, b) => a.compareTo(b));
|
||||
final lastUpdated = lastUpdatedList.firstOrNull;
|
||||
if (entries.isNotEmpty) {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
if (lastUpdated != null)
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 20),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate.fixed([
|
||||
Text(
|
||||
l10n.library_last_updated(dateFormat(
|
||||
lastUpdated.toString(),
|
||||
ref: ref,
|
||||
context: context,
|
||||
showHOURorMINUTE: true)),
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: context.secondaryColor))
|
||||
])),
|
||||
),
|
||||
SliverGroupedListView<Feed, String>(
|
||||
elements: entries,
|
||||
groupBy: (element) => dateFormat(element.date!,
|
||||
context: context,
|
||||
ref: ref,
|
||||
forHistoryValue: true,
|
||||
useRelativeTimesTamps: false),
|
||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8, left: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(dateFormat(
|
||||
null,
|
||||
context: context,
|
||||
stringDate: groupByValue,
|
||||
ref: ref,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, Feed element) {
|
||||
final chapter = element.chapter.value!;
|
||||
return FeedChapterListTileWidget(
|
||||
chapter: chapter, sourceExist: true);
|
||||
},
|
||||
itemComparator: (item1, item2) =>
|
||||
item1.date!.compareTo(item2.date!),
|
||||
order: GroupedListOrder.DESC,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: Text(l10n.no_recent_updates),
|
||||
);
|
||||
},
|
||||
error: (Object error, StackTrace stackTrace) {
|
||||
return ErrorText(error);
|
||||
},
|
||||
loading: () {
|
||||
return const ProgressCenter();
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
|
@ -19,9 +19,9 @@ Stream<List<History>> getAllHistoryStream(GetAllHistoryStreamRef ref,
|
|||
}
|
||||
|
||||
@riverpod
|
||||
Stream<List<Feed>> getAllFeedStream(GetAllFeedStreamRef ref,
|
||||
Stream<List<Update>> getAllUpdateStream(GetAllUpdateStreamRef ref,
|
||||
{required bool isManga}) async* {
|
||||
yield* isar.feeds
|
||||
yield* isar.updates
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.and()
|
||||
|
|
|
|||
|
|
@ -158,29 +158,30 @@ class _GetAllHistoryStreamProviderElement
|
|||
bool get isManga => (origin as GetAllHistoryStreamProvider).isManga;
|
||||
}
|
||||
|
||||
String _$getAllFeedStreamHash() => r'3d60bca5377bf6fc2aee36e7bec5b319b2377add';
|
||||
String _$getAllUpdateStreamHash() =>
|
||||
r'9f62b36ef0b268ee8c3cc93a10f8963def8dfbb0';
|
||||
|
||||
/// See also [getAllFeedStream].
|
||||
@ProviderFor(getAllFeedStream)
|
||||
const getAllFeedStreamProvider = GetAllFeedStreamFamily();
|
||||
/// See also [getAllUpdateStream].
|
||||
@ProviderFor(getAllUpdateStream)
|
||||
const getAllUpdateStreamProvider = GetAllUpdateStreamFamily();
|
||||
|
||||
/// See also [getAllFeedStream].
|
||||
class GetAllFeedStreamFamily extends Family<AsyncValue<List<Feed>>> {
|
||||
/// See also [getAllFeedStream].
|
||||
const GetAllFeedStreamFamily();
|
||||
/// See also [getAllUpdateStream].
|
||||
class GetAllUpdateStreamFamily extends Family<AsyncValue<List<Update>>> {
|
||||
/// See also [getAllUpdateStream].
|
||||
const GetAllUpdateStreamFamily();
|
||||
|
||||
/// See also [getAllFeedStream].
|
||||
GetAllFeedStreamProvider call({
|
||||
/// See also [getAllUpdateStream].
|
||||
GetAllUpdateStreamProvider call({
|
||||
required bool isManga,
|
||||
}) {
|
||||
return GetAllFeedStreamProvider(
|
||||
return GetAllUpdateStreamProvider(
|
||||
isManga: isManga,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
GetAllFeedStreamProvider getProviderOverride(
|
||||
covariant GetAllFeedStreamProvider provider,
|
||||
GetAllUpdateStreamProvider getProviderOverride(
|
||||
covariant GetAllUpdateStreamProvider provider,
|
||||
) {
|
||||
return call(
|
||||
isManga: provider.isManga,
|
||||
|
|
@ -199,32 +200,33 @@ class GetAllFeedStreamFamily extends Family<AsyncValue<List<Feed>>> {
|
|||
_allTransitiveDependencies;
|
||||
|
||||
@override
|
||||
String? get name => r'getAllFeedStreamProvider';
|
||||
String? get name => r'getAllUpdateStreamProvider';
|
||||
}
|
||||
|
||||
/// See also [getAllFeedStream].
|
||||
class GetAllFeedStreamProvider extends AutoDisposeStreamProvider<List<Feed>> {
|
||||
/// See also [getAllFeedStream].
|
||||
GetAllFeedStreamProvider({
|
||||
/// See also [getAllUpdateStream].
|
||||
class GetAllUpdateStreamProvider
|
||||
extends AutoDisposeStreamProvider<List<Update>> {
|
||||
/// See also [getAllUpdateStream].
|
||||
GetAllUpdateStreamProvider({
|
||||
required bool isManga,
|
||||
}) : this._internal(
|
||||
(ref) => getAllFeedStream(
|
||||
ref as GetAllFeedStreamRef,
|
||||
(ref) => getAllUpdateStream(
|
||||
ref as GetAllUpdateStreamRef,
|
||||
isManga: isManga,
|
||||
),
|
||||
from: getAllFeedStreamProvider,
|
||||
name: r'getAllFeedStreamProvider',
|
||||
from: getAllUpdateStreamProvider,
|
||||
name: r'getAllUpdateStreamProvider',
|
||||
debugGetCreateSourceHash:
|
||||
const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$getAllFeedStreamHash,
|
||||
dependencies: GetAllFeedStreamFamily._dependencies,
|
||||
: _$getAllUpdateStreamHash,
|
||||
dependencies: GetAllUpdateStreamFamily._dependencies,
|
||||
allTransitiveDependencies:
|
||||
GetAllFeedStreamFamily._allTransitiveDependencies,
|
||||
GetAllUpdateStreamFamily._allTransitiveDependencies,
|
||||
isManga: isManga,
|
||||
);
|
||||
|
||||
GetAllFeedStreamProvider._internal(
|
||||
GetAllUpdateStreamProvider._internal(
|
||||
super._createNotifier, {
|
||||
required super.name,
|
||||
required super.dependencies,
|
||||
|
|
@ -238,12 +240,12 @@ class GetAllFeedStreamProvider extends AutoDisposeStreamProvider<List<Feed>> {
|
|||
|
||||
@override
|
||||
Override overrideWith(
|
||||
Stream<List<Feed>> Function(GetAllFeedStreamRef provider) create,
|
||||
Stream<List<Update>> Function(GetAllUpdateStreamRef provider) create,
|
||||
) {
|
||||
return ProviderOverride(
|
||||
origin: this,
|
||||
override: GetAllFeedStreamProvider._internal(
|
||||
(ref) => create(ref as GetAllFeedStreamRef),
|
||||
override: GetAllUpdateStreamProvider._internal(
|
||||
(ref) => create(ref as GetAllUpdateStreamRef),
|
||||
from: from,
|
||||
name: null,
|
||||
dependencies: null,
|
||||
|
|
@ -255,13 +257,13 @@ class GetAllFeedStreamProvider extends AutoDisposeStreamProvider<List<Feed>> {
|
|||
}
|
||||
|
||||
@override
|
||||
AutoDisposeStreamProviderElement<List<Feed>> createElement() {
|
||||
return _GetAllFeedStreamProviderElement(this);
|
||||
AutoDisposeStreamProviderElement<List<Update>> createElement() {
|
||||
return _GetAllUpdateStreamProviderElement(this);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return other is GetAllFeedStreamProvider && other.isManga == isManga;
|
||||
return other is GetAllUpdateStreamProvider && other.isManga == isManga;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -273,18 +275,18 @@ class GetAllFeedStreamProvider extends AutoDisposeStreamProvider<List<Feed>> {
|
|||
}
|
||||
}
|
||||
|
||||
mixin GetAllFeedStreamRef on AutoDisposeStreamProviderRef<List<Feed>> {
|
||||
mixin GetAllUpdateStreamRef on AutoDisposeStreamProviderRef<List<Update>> {
|
||||
/// The parameter `isManga` of this provider.
|
||||
bool get isManga;
|
||||
}
|
||||
|
||||
class _GetAllFeedStreamProviderElement
|
||||
extends AutoDisposeStreamProviderElement<List<Feed>>
|
||||
with GetAllFeedStreamRef {
|
||||
_GetAllFeedStreamProviderElement(super.provider);
|
||||
class _GetAllUpdateStreamProviderElement
|
||||
extends AutoDisposeStreamProviderElement<List<Update>>
|
||||
with GetAllUpdateStreamRef {
|
||||
_GetAllUpdateStreamProviderElement(super.provider);
|
||||
|
||||
@override
|
||||
bool get isManga => (origin as GetAllFeedStreamProvider).isManga;
|
||||
bool get isManga => (origin as GetAllUpdateStreamProvider).isManga;
|
||||
}
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import 'package:mangayomi/models/download.dart';
|
|||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/modules/library/providers/add_torrent.dart';
|
||||
import 'package:mangayomi/modules/library/providers/local_archive.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_providers.dart';
|
||||
|
|
@ -59,26 +59,21 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
botToast(context.l10n.updating_library,
|
||||
fontSize: 13, second: 1600, alignY: 0.8);
|
||||
int numbers = 0;
|
||||
try {
|
||||
for (var manga in mangaList) {
|
||||
ref
|
||||
.watch(updateMangaDetailProvider(mangaId: manga.id, isInit: false)
|
||||
.future)
|
||||
.then((value) {
|
||||
numbers++;
|
||||
});
|
||||
}
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (mangaList.length == numbers) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
BotToast.cleanAll();
|
||||
} catch (e) {
|
||||
BotToast.cleanAll();
|
||||
for (var manga in mangaList) {
|
||||
try {
|
||||
await ref.read(
|
||||
updateMangaDetailProvider(mangaId: manga.id, isInit: false).future);
|
||||
} catch (_) {}
|
||||
numbers++;
|
||||
}
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (mangaList.length == numbers) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
BotToast.cleanAll();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -1165,7 +1160,7 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
|
|||
.notifier)
|
||||
.addUpdatedChapter(
|
||||
chapter, true, false);
|
||||
isar.feeds
|
||||
isar.updates
|
||||
.filter()
|
||||
.mangaIdEqualTo(chapter.mangaId)
|
||||
.chapterNameEqualTo(chapter.name)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import 'package:go_router/go_router.dart';
|
|||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/source.dart';
|
||||
import 'package:mangayomi/modules/widgets/loading_icon.dart';
|
||||
import 'package:mangayomi/services/fetch_anime_sources.dart';
|
||||
|
|
@ -42,11 +42,10 @@ class MainScreen extends ConsumerWidget {
|
|||
bool isReadingScreen =
|
||||
location == '/mangareaderview' || location == '/animePlayerView';
|
||||
int currentIndex = switch (location) {
|
||||
null => 0,
|
||||
'/MangaLibrary' => 0,
|
||||
null || '/MangaLibrary' => 0,
|
||||
'/AnimeLibrary' => 1,
|
||||
'/history' => 2,
|
||||
'/feed' => 3,
|
||||
'/updates' => 2,
|
||||
'/history' => 3,
|
||||
'/browse' => 4,
|
||||
_ => 5,
|
||||
};
|
||||
|
|
@ -98,7 +97,7 @@ class MainScreen extends ConsumerWidget {
|
|||
!= '/MangaLibrary' &&
|
||||
!= '/AnimeLibrary' &&
|
||||
!= '/history' &&
|
||||
!= '/feed' &&
|
||||
!= '/updates' &&
|
||||
!= '/browse' &&
|
||||
!= '/more' =>
|
||||
0,
|
||||
|
|
@ -113,103 +112,112 @@ class MainScreen extends ConsumerWidget {
|
|||
borderRadius:
|
||||
BorderRadius.circular(30)),
|
||||
),
|
||||
child: NavigationRail(
|
||||
labelType: NavigationRailLabelType.all,
|
||||
useIndicator: true,
|
||||
destinations: [
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.collections_bookmark),
|
||||
icon: const Icon(Icons
|
||||
.collections_bookmark_outlined),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.manga))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.video_collection),
|
||||
icon: const Icon(
|
||||
Icons.video_collection_outlined),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.anime))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.history),
|
||||
icon: const Icon(
|
||||
Icons.history_outlined),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.history))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: Stack(
|
||||
children: [
|
||||
const Icon(Icons.rss_feed),
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: _feedTotalNumbers(
|
||||
ref, false))
|
||||
],
|
||||
),
|
||||
icon: Stack(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.rss_feed_outlined),
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: _feedTotalNumbers(
|
||||
ref, false))
|
||||
],
|
||||
),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Stack(
|
||||
children: [
|
||||
Text(l10n.feed),
|
||||
],
|
||||
))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.explore),
|
||||
icon: const Icon(
|
||||
Icons.explore_outlined),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.browse))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.more_horiz),
|
||||
icon: const Icon(
|
||||
Icons.more_horiz_outlined),
|
||||
label: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 5),
|
||||
child: Text(l10n.more))),
|
||||
],
|
||||
selectedIndex: currentIndex,
|
||||
onDestinationSelected: (newIndex) {
|
||||
if (newIndex == 0) {
|
||||
route.go('/MangaLibrary');
|
||||
} else if (newIndex == 1) {
|
||||
route.go('/AnimeLibrary');
|
||||
} else if (newIndex == 2) {
|
||||
route.go('/history');
|
||||
} else if (newIndex == 3) {
|
||||
route.go('/feed');
|
||||
} else if (newIndex == 4) {
|
||||
route.go('/browse');
|
||||
} else if (newIndex == 5) {
|
||||
route.go('/more');
|
||||
}
|
||||
},
|
||||
),
|
||||
child: Builder(builder: (context) {
|
||||
final updatesTotalNumbersWidget = Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: _updatesTotalNumbers(ref, false));
|
||||
final extensionUpdateTotalNumbersWidget =
|
||||
Positioned(
|
||||
right: 0,
|
||||
top: 0,
|
||||
child: _extensionUpdateTotalNumbers(
|
||||
ref));
|
||||
return NavigationRail(
|
||||
labelType: NavigationRailLabelType.all,
|
||||
useIndicator: true,
|
||||
destinations: [
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.collections_bookmark),
|
||||
icon: const Icon(Icons
|
||||
.collections_bookmark_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Text(l10n.manga))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: const Icon(
|
||||
Icons.video_collection),
|
||||
icon: const Icon(Icons
|
||||
.video_collection_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Text(l10n.anime))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: Stack(
|
||||
children: [
|
||||
const Icon(Icons.new_releases),
|
||||
updatesTotalNumbersWidget
|
||||
],
|
||||
),
|
||||
icon: Stack(
|
||||
children: [
|
||||
const Icon(Icons
|
||||
.new_releases_outlined),
|
||||
updatesTotalNumbersWidget
|
||||
],
|
||||
),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Stack(
|
||||
children: [
|
||||
Text(l10n.updates),
|
||||
],
|
||||
))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.history),
|
||||
icon: const Icon(
|
||||
Icons.history_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Text(l10n.history))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon: Stack(
|
||||
children: [
|
||||
const Icon(Icons.explore),
|
||||
extensionUpdateTotalNumbersWidget
|
||||
],
|
||||
),
|
||||
icon: Stack(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.explore_outlined),
|
||||
extensionUpdateTotalNumbersWidget
|
||||
],
|
||||
),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Text(l10n.browse))),
|
||||
NavigationRailDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.more_horiz),
|
||||
icon: const Icon(
|
||||
Icons.more_horiz_outlined),
|
||||
label: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 5),
|
||||
child: Text(l10n.more))),
|
||||
],
|
||||
selectedIndex: currentIndex,
|
||||
onDestinationSelected: (newIndex) {
|
||||
final fn = switch (newIndex) {
|
||||
0 => route.go('/MangaLibrary'),
|
||||
1 => route.go('/AnimeLibrary'),
|
||||
2 => route.go('/updates'),
|
||||
3 => route.go('/history'),
|
||||
4 => route.go('/browse'),
|
||||
_ => route.go('/more'),
|
||||
};
|
||||
fn;
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
Positioned(
|
||||
right: 18,
|
||||
|
|
@ -234,7 +242,7 @@ class MainScreen extends ConsumerWidget {
|
|||
!= '/MangaLibrary' &&
|
||||
!= '/AnimeLibrary' &&
|
||||
!= '/history' &&
|
||||
!= '/feed' &&
|
||||
!= '/updates' &&
|
||||
!= '/browse' &&
|
||||
!= '/more' =>
|
||||
0,
|
||||
|
|
@ -263,22 +271,24 @@ class MainScreen extends ConsumerWidget {
|
|||
icon: const Icon(
|
||||
Icons.video_collection_outlined),
|
||||
label: l10n.anime),
|
||||
Stack(
|
||||
children: [
|
||||
NavigationDestination(
|
||||
selectedIcon:
|
||||
const Icon(Icons.new_releases),
|
||||
icon: const Icon(
|
||||
Icons.new_releases_outlined),
|
||||
label: l10n.updates),
|
||||
Positioned(
|
||||
right: 14,
|
||||
top: 3,
|
||||
child: _updatesTotalNumbers(ref, true)),
|
||||
],
|
||||
),
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(Icons.history),
|
||||
icon: const Icon(Icons.history_outlined),
|
||||
label: l10n.history),
|
||||
Stack(
|
||||
children: [
|
||||
NavigationDestination(
|
||||
selectedIcon: const Icon(Icons.rss_feed),
|
||||
icon: const Icon(Icons.rss_feed_outlined),
|
||||
label: l10n.feed),
|
||||
Positioned(
|
||||
right: 14,
|
||||
top: 3,
|
||||
child: _feedTotalNumbers(ref, true)),
|
||||
],
|
||||
),
|
||||
Stack(
|
||||
children: [
|
||||
NavigationDestination(
|
||||
|
|
@ -297,19 +307,15 @@ class MainScreen extends ConsumerWidget {
|
|||
label: l10n.more),
|
||||
],
|
||||
onDestinationSelected: (newIndex) {
|
||||
if (newIndex == 0) {
|
||||
route.go('/MangaLibrary');
|
||||
} else if (newIndex == 1) {
|
||||
route.go('/AnimeLibrary');
|
||||
} else if (newIndex == 2) {
|
||||
route.go('/history');
|
||||
} else if (newIndex == 3) {
|
||||
route.go('/feed');
|
||||
} else if (newIndex == 4) {
|
||||
route.go('/browse');
|
||||
} else if (newIndex == 5) {
|
||||
route.go('/more');
|
||||
}
|
||||
final fn = switch (newIndex) {
|
||||
0 => route.go('/MangaLibrary'),
|
||||
1 => route.go('/AnimeLibrary'),
|
||||
2 => route.go('/updates'),
|
||||
3 => route.go('/history'),
|
||||
4 => route.go('/browse'),
|
||||
_ => route.go('/more'),
|
||||
};
|
||||
fn;
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
@ -366,9 +372,9 @@ Widget _extensionUpdateTotalNumbers(WidgetRef ref) {
|
|||
});
|
||||
}
|
||||
|
||||
Widget _feedTotalNumbers(WidgetRef ref, bool mobile) {
|
||||
Widget _updatesTotalNumbers(WidgetRef ref, bool mobile) {
|
||||
return StreamBuilder(
|
||||
stream: isar.feeds.filter().idIsNotNull().watch(fireImmediately: true),
|
||||
stream: isar.updates.filter().idIsNotNull().watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||
final entries = snapshot.data!.where((element) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
|||
import 'package:mangayomi/eval/dart/model/m_manga.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
|
||||
import 'package:mangayomi/services/get_detail.dart';
|
||||
|
|
@ -85,13 +85,13 @@ Future<dynamic> updateMangaDetail(UpdateMangaDetailRef ref,
|
|||
isar.chapters.putSync(chap);
|
||||
chap.manga.saveSync();
|
||||
if (manga.chapters.isNotEmpty) {
|
||||
final feed = Feed(
|
||||
final update = Update(
|
||||
mangaId: mangaId,
|
||||
chapterName: chap.name,
|
||||
date: DateTime.now().millisecondsSinceEpoch.toString())
|
||||
..chapter.value = chap;
|
||||
isar.feeds.putSync(feed);
|
||||
feed.chapter.saveSync();
|
||||
isar.updates.putSync(update);
|
||||
update.chapter.saveSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$updateMangaDetailHash() => r'f72eb5e66fd9fb7ed61aa08365e068d77737438d';
|
||||
String _$updateMangaDetailHash() => r'736b68c65f624da85b15c0a7a2a263aab8e8df7e';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import 'package:mangayomi/main.dart';
|
|||
import 'package:mangayomi/models/category.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
@ -61,8 +61,8 @@ void doRestore(DoRestoreRef ref,
|
|||
final extensionsPref = (backup["extensions_preferences"] as List?)
|
||||
?.map((e) => SourcePreference.fromJson(e))
|
||||
.toList();
|
||||
final feeds =
|
||||
(backup["feeds"] as List?)?.map((e) => Feed.fromJson(e)).toList();
|
||||
final updates =
|
||||
(backup["updates"] as List?)?.map((e) => Update.fromJson(e)).toList();
|
||||
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.clearSync();
|
||||
|
|
@ -100,19 +100,19 @@ void doRestore(DoRestoreRef ref,
|
|||
}
|
||||
}
|
||||
|
||||
isar.feeds.clearSync();
|
||||
if (feeds != null) {
|
||||
isar.updates.clearSync();
|
||||
if (updates != null) {
|
||||
final tempChapters =
|
||||
isar.chapters.filter().idIsNotNull().findAllSync().toList();
|
||||
for (var feed in feeds) {
|
||||
for (var update in updates) {
|
||||
final matchingChapter = tempChapters
|
||||
.where((chapter) =>
|
||||
chapter.mangaId == feed.mangaId &&
|
||||
chapter.name == feed.chapterName)
|
||||
chapter.mangaId == update.mangaId &&
|
||||
chapter.name == update.chapterName)
|
||||
.firstOrNull;
|
||||
if (matchingChapter != null) {
|
||||
isar.feeds.putSync(feed..chapter.value = matchingChapter);
|
||||
feed.chapter.saveSync();
|
||||
isar.updates.putSync(update..chapter.value = matchingChapter);
|
||||
update.chapter.saveSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'restore.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$doRestoreHash() => r'823b26bade20d89ae7b7b56a7eb7c25020795b45';
|
||||
String _$doRestoreHash() => r'69153ba0467229d219346aab9e6ec87c52f66095';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -1,30 +1,324 @@
|
|||
import 'package:bot_toast/bot_toast.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:grouped_list/sliver_grouped_list.dart';
|
||||
|
||||
class UpdatesScreen extends StatelessWidget {
|
||||
import 'package:isar/isar.dart';
|
||||
import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/modules/manga/detail/providers/update_manga_detail_providers.dart';
|
||||
import 'package:mangayomi/modules/updates/widgets/update_chapter_list_tile_widget.dart';
|
||||
import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
import 'package:mangayomi/modules/widgets/error_text.dart';
|
||||
import 'package:mangayomi/modules/widgets/progress_center.dart';
|
||||
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
|
||||
|
||||
class UpdatesScreen extends ConsumerStatefulWidget {
|
||||
const UpdatesScreen({super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<UpdatesScreen> createState() => _UpdatesScreenState();
|
||||
}
|
||||
|
||||
class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
|
||||
with TickerProviderStateMixin {
|
||||
late TabController _tabBarController;
|
||||
bool _isLoading = false;
|
||||
Future<void> _updateLibrary() async {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
botToast(context.l10n.updating_library,
|
||||
fontSize: 13, second: 1600, alignY: 0.8);
|
||||
final mangaList =
|
||||
isar.mangas.filter().idIsNotNull().favoriteEqualTo(true).findAllSync();
|
||||
int numbers = 0;
|
||||
|
||||
for (var manga in mangaList) {
|
||||
try {
|
||||
await ref.read(
|
||||
updateMangaDetailProvider(mangaId: manga.id, isInit: false).future);
|
||||
} catch (_) {}
|
||||
numbers++;
|
||||
}
|
||||
await Future.doWhile(() async {
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
if (mangaList.length == numbers) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
BotToast.cleanAll();
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_tabBarController = TabController(length: 2, vsync: this);
|
||||
_tabBarController.animateTo(0);
|
||||
_tabBarController.addListener(() {
|
||||
setState(() {
|
||||
_textEditingController.clear();
|
||||
_isSearch = false;
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
final _textEditingController = TextEditingController();
|
||||
bool _isSearch = false;
|
||||
List<History> entriesData = [];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context);
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: Text(
|
||||
l10n!.updates,
|
||||
style: TextStyle(color: Theme.of(context).hintColor),
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return DefaultTabController(
|
||||
animationDuration: Duration.zero,
|
||||
length: 2,
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: _isSearch
|
||||
? null
|
||||
: Text(
|
||||
l10n.updates,
|
||||
style: TextStyle(color: Theme.of(context).hintColor),
|
||||
),
|
||||
actions: [
|
||||
_isSearch
|
||||
? SeachFormTextField(
|
||||
onChanged: (value) {
|
||||
setState(() {});
|
||||
},
|
||||
onSuffixPressed: () {
|
||||
_textEditingController.clear();
|
||||
setState(() {});
|
||||
},
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = false;
|
||||
});
|
||||
_textEditingController.clear();
|
||||
},
|
||||
controller: _textEditingController,
|
||||
)
|
||||
: IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
_isSearch = true;
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.search_outlined,
|
||||
color: Theme.of(context).hintColor)),
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
_updateLibrary();
|
||||
},
|
||||
icon: Icon(Icons.refresh_outlined,
|
||||
color: Theme.of(context).hintColor)),
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
l10n.remove_everything,
|
||||
),
|
||||
content: Text(l10n.remove_all_update_msg),
|
||||
actions: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Text(l10n.cancel)),
|
||||
const SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
List<Update> updates = isar.updates
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.chapter((q) => q.manga((q) =>
|
||||
q.isMangaEqualTo(
|
||||
_tabBarController.index ==
|
||||
0)))
|
||||
.findAllSync()
|
||||
.toList();
|
||||
isar.writeTxnSync(() {
|
||||
for (var update in updates) {
|
||||
isar.updates.deleteSync(update.id!);
|
||||
}
|
||||
});
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: Text(l10n.ok)),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
});
|
||||
},
|
||||
icon: Icon(Icons.delete_sweep_outlined,
|
||||
color: Theme.of(context).hintColor)),
|
||||
],
|
||||
bottom: TabBar(
|
||||
indicatorSize: TabBarIndicatorSize.tab,
|
||||
controller: _tabBarController,
|
||||
tabs: [
|
||||
Tab(text: l10n.manga),
|
||||
Tab(text: l10n.anime),
|
||||
],
|
||||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: TabBarView(controller: _tabBarController, children: [
|
||||
UpdateTab(
|
||||
isManga: true,
|
||||
query: _textEditingController.text,
|
||||
isLoading: _isLoading),
|
||||
UpdateTab(
|
||||
isManga: false,
|
||||
query: _textEditingController.text,
|
||||
isLoading: _isLoading)
|
||||
]),
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
splashRadius: 20,
|
||||
onPressed: () {},
|
||||
icon: Icon(Icons.refresh, color: Theme.of(context).hintColor)),
|
||||
],
|
||||
),
|
||||
body: Center(
|
||||
child: Text(l10n.no_recent_updates),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateTab extends ConsumerStatefulWidget {
|
||||
final String query;
|
||||
final bool isManga;
|
||||
final bool isLoading;
|
||||
const UpdateTab(
|
||||
{required this.isManga,
|
||||
required this.query,
|
||||
required this.isLoading,
|
||||
super.key});
|
||||
|
||||
@override
|
||||
ConsumerState<UpdateTab> createState() => _UpdateTabState();
|
||||
}
|
||||
|
||||
class _UpdateTabState extends ConsumerState<UpdateTab> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
final update =
|
||||
ref.watch(getAllUpdateStreamProvider(isManga: widget.isManga));
|
||||
return Scaffold(
|
||||
body: Stack(
|
||||
children: [
|
||||
update.when(
|
||||
data: (data) {
|
||||
final entries = data
|
||||
.where((element) => widget.query.isNotEmpty
|
||||
? element.chapter.value!.manga.value!.name!
|
||||
.toLowerCase()
|
||||
.contains(widget.query.toLowerCase())
|
||||
: true)
|
||||
.toList();
|
||||
final lastUpdatedList = data
|
||||
.map((e) => e.chapter.value!.manga.value!.lastUpdate!)
|
||||
.toList();
|
||||
lastUpdatedList.sort((a, b) => a.compareTo(b));
|
||||
final lastUpdated = lastUpdatedList.firstOrNull;
|
||||
if (entries.isNotEmpty) {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
if (lastUpdated != null)
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 10, right: 10, top: 10, bottom: 20),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate.fixed([
|
||||
Text(
|
||||
l10n.library_last_updated(dateFormat(
|
||||
lastUpdated.toString(),
|
||||
ref: ref,
|
||||
context: context,
|
||||
showHOURorMINUTE: true)),
|
||||
style: TextStyle(
|
||||
fontStyle: FontStyle.italic,
|
||||
color: context.secondaryColor))
|
||||
])),
|
||||
),
|
||||
SliverGroupedListView<Update, String>(
|
||||
elements: entries,
|
||||
groupBy: (element) => dateFormat(element.date!,
|
||||
context: context,
|
||||
ref: ref,
|
||||
forHistoryValue: true,
|
||||
useRelativeTimesTamps: false),
|
||||
groupSeparatorBuilder: (String groupByValue) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 8, left: 12),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(dateFormat(
|
||||
null,
|
||||
context: context,
|
||||
stringDate: groupByValue,
|
||||
ref: ref,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
itemBuilder: (context, element) {
|
||||
final chapter = element.chapter.value!;
|
||||
return UpdateChapterListTileWidget(
|
||||
chapter: chapter, sourceExist: true);
|
||||
},
|
||||
itemComparator: (item1, item2) =>
|
||||
item1.date!.compareTo(item2.date!),
|
||||
order: GroupedListOrder.DESC,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: Text(l10n.no_recent_updates),
|
||||
);
|
||||
},
|
||||
error: (Object error, StackTrace stackTrace) {
|
||||
return ErrorText(error);
|
||||
},
|
||||
loading: () {
|
||||
return const ProgressCenter();
|
||||
},
|
||||
),
|
||||
if (widget.isLoading)
|
||||
const Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(top: 40),
|
||||
child: Center(
|
||||
child: RefreshProgressIndicator(),
|
||||
),
|
||||
)),
|
||||
],
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import 'package:mangayomi/modules/manga/download/download_page_widget.dart';
|
|||
import 'package:mangayomi/utils/extensions/chapter.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
|
||||
class FeedChapterListTileWidget extends ConsumerWidget {
|
||||
class UpdateChapterListTileWidget extends ConsumerWidget {
|
||||
final Chapter chapter;
|
||||
final bool sourceExist;
|
||||
const FeedChapterListTileWidget({
|
||||
const UpdateChapterListTileWidget({
|
||||
required this.chapter,
|
||||
required this.sourceExist,
|
||||
super.key,
|
||||
|
|
@ -7,7 +7,7 @@ import 'package:mangayomi/models/category.dart';
|
|||
import 'package:mangayomi/models/changed_items.dart';
|
||||
import 'package:mangayomi/models/chapter.dart';
|
||||
import 'package:mangayomi/models/download.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/history.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
import 'package:mangayomi/models/settings.dart';
|
||||
|
|
@ -132,7 +132,7 @@ class StorageProvider {
|
|||
ChangedItemsSchema,
|
||||
ChapterSchema,
|
||||
CategorySchema,
|
||||
FeedSchema,
|
||||
UpdateSchema,
|
||||
HistorySchema,
|
||||
DownloadSchema,
|
||||
SourceSchema,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import 'package:mangayomi/modules/browse/extension/edit_code.dart';
|
|||
import 'package:mangayomi/modules/browse/extension/extension_detail.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/widgets/create_extension.dart';
|
||||
import 'package:mangayomi/modules/browse/sources/sources_filter_screen.dart';
|
||||
import 'package:mangayomi/modules/feed/feed_screen.dart';
|
||||
import 'package:mangayomi/modules/updates/updates_screen.dart';
|
||||
import 'package:mangayomi/modules/more/backup_and_restore/backup_and_restore.dart';
|
||||
import 'package:mangayomi/modules/more/categories/categories_screen.dart';
|
||||
import 'package:mangayomi/modules/more/settings/downloads/downloads_screen.dart';
|
||||
|
|
@ -19,7 +19,6 @@ import 'package:mangayomi/modules/more/settings/sync/sync.dart';
|
|||
import 'package:mangayomi/modules/more/settings/track/track.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/manage_trackers/manage_trackers.dart';
|
||||
import 'package:mangayomi/modules/more/settings/track/manage_trackers/tracking_detail.dart';
|
||||
import 'package:mangayomi/modules/updates/updates_screen.dart';
|
||||
import 'package:mangayomi/modules/webview/webview.dart';
|
||||
import 'package:mangayomi/modules/browse/browse_screen.dart';
|
||||
import 'package:mangayomi/modules/browse/extension/extension_lang.dart';
|
||||
|
|
@ -117,12 +116,12 @@ class RouterNotifier extends ChangeNotifier {
|
|||
),
|
||||
),
|
||||
GoRoute(
|
||||
name: "feed",
|
||||
path: '/feed',
|
||||
builder: (context, state) => const FeedScreen(),
|
||||
name: "updates",
|
||||
path: '/updates',
|
||||
builder: (context, state) => const UpdatesScreen(),
|
||||
pageBuilder: (context, state) => transitionPage(
|
||||
key: state.pageKey,
|
||||
child: const FeedScreen(),
|
||||
child: const UpdatesScreen(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
|
|
@ -144,15 +143,6 @@ class RouterNotifier extends ChangeNotifier {
|
|||
),
|
||||
),
|
||||
]),
|
||||
GoRoute(
|
||||
name: "updates",
|
||||
path: '/updates',
|
||||
builder: (context, state) => const UpdatesScreen(),
|
||||
pageBuilder: (context, state) => transitionPage(
|
||||
key: state.pageKey,
|
||||
child: const UpdatesScreen(),
|
||||
),
|
||||
),
|
||||
GoRoute(
|
||||
path: "/mangaHome",
|
||||
name: "mangaHome",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import 'package:mangayomi/eval/dart/model/m_bridge.dart';
|
|||
import 'package:mangayomi/eval/dart/model/source_preference.dart';
|
||||
import 'package:mangayomi/main.dart';
|
||||
import 'package:mangayomi/models/changed_items.dart';
|
||||
import 'package:mangayomi/models/feed.dart';
|
||||
import 'package:mangayomi/models/update.dart';
|
||||
import 'package:mangayomi/models/sync_preference.dart';
|
||||
import 'package:mangayomi/models/track.dart';
|
||||
import 'package:mangayomi/models/manga.dart';
|
||||
|
|
@ -206,7 +206,7 @@ class SyncServer extends _$SyncServer {
|
|||
datas["chapters"] = data["chapters"];
|
||||
datas["tracks"] = data["tracks"];
|
||||
datas["history"] = data["history"];
|
||||
datas["feeds"] = data["feeds"];
|
||||
datas["updates"] = data["updates"];
|
||||
var encodedJson = jsonEncode(datas);
|
||||
return sha256.convert(utf8.encode(encodedJson)).toString();
|
||||
}
|
||||
|
|
@ -296,13 +296,13 @@ class SyncServer extends _$SyncServer {
|
|||
.map((e) => e.toJson())
|
||||
.toList();
|
||||
datas.addAll({"extensions_preferences": sourcePreferences});
|
||||
final feeds = isar.feeds
|
||||
final updates = isar.updates
|
||||
.filter()
|
||||
.idIsNotNull()
|
||||
.findAllSync()
|
||||
.map((e) => e.toJson())
|
||||
.toList();
|
||||
datas.addAll({"feeds": feeds});
|
||||
datas.addAll({"updates": updates});
|
||||
return datas;
|
||||
}
|
||||
|
||||
|
|
@ -322,8 +322,8 @@ class SyncServer extends _$SyncServer {
|
|||
final history = (backup["history"] as List?)
|
||||
?.map((e) => History.fromJson(e))
|
||||
.toList();
|
||||
final feeds =
|
||||
(backup["feeds"] as List?)?.map((e) => Feed.fromJson(e)).toList();
|
||||
final updates =
|
||||
(backup["updates"] as List?)?.map((e) => Update.fromJson(e)).toList();
|
||||
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.clearSync();
|
||||
|
|
@ -350,19 +350,19 @@ class SyncServer extends _$SyncServer {
|
|||
}
|
||||
}
|
||||
|
||||
isar.feeds.clearSync();
|
||||
if (feeds != null) {
|
||||
isar.updates.clearSync();
|
||||
if (updates != null) {
|
||||
final tempChapters =
|
||||
isar.chapters.filter().idIsNotNull().findAllSync().toList();
|
||||
for (var feed in feeds) {
|
||||
for (var update in updates) {
|
||||
final matchingChapter = tempChapters
|
||||
.where((chapter) =>
|
||||
chapter.mangaId == feed.mangaId &&
|
||||
chapter.name == feed.chapterName)
|
||||
chapter.mangaId == update.mangaId &&
|
||||
chapter.name == update.chapterName)
|
||||
.firstOrNull;
|
||||
if (matchingChapter != null) {
|
||||
isar.feeds.putSync(feed..chapter.value = matchingChapter);
|
||||
feed.chapter.saveSync();
|
||||
isar.updates.putSync(update..chapter.value = matchingChapter);
|
||||
update.chapter.saveSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -416,8 +416,8 @@ class SyncServer extends _$SyncServer {
|
|||
final extensionsPref = (backup["extensions_preferences"] as List?)
|
||||
?.map((e) => SourcePreference.fromJson(e))
|
||||
.toList();
|
||||
final feeds =
|
||||
(backup["feeds"] as List?)?.map((e) => Feed.fromJson(e)).toList();
|
||||
final updates =
|
||||
(backup["updates"] as List?)?.map((e) => Update.fromJson(e)).toList();
|
||||
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.clearSync();
|
||||
|
|
@ -444,19 +444,19 @@ class SyncServer extends _$SyncServer {
|
|||
}
|
||||
}
|
||||
|
||||
isar.feeds.clearSync();
|
||||
if (feeds != null) {
|
||||
isar.updates.clearSync();
|
||||
if (updates != null) {
|
||||
final tempChapters =
|
||||
isar.chapters.filter().idIsNotNull().findAllSync().toList();
|
||||
for (var feed in feeds) {
|
||||
for (var update in updates) {
|
||||
final matchingChapter = tempChapters
|
||||
.where((chapter) =>
|
||||
chapter.mangaId == feed.mangaId &&
|
||||
chapter.name == feed.chapterName)
|
||||
chapter.mangaId == update.mangaId &&
|
||||
chapter.name == update.chapterName)
|
||||
.firstOrNull;
|
||||
if (matchingChapter != null) {
|
||||
isar.feeds.putSync(feed..chapter.value = matchingChapter);
|
||||
feed.chapter.saveSync();
|
||||
isar.updates.putSync(update..chapter.value = matchingChapter);
|
||||
update.chapter.saveSync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'sync_server.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$syncServerHash() => r'e019e8870184d25f7a2659e35f6c3969bc683b50';
|
||||
String _$syncServerHash() => r'0f4a07754abea35efb563ba8471b47d1c8854058';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
Loading…
Reference in a new issue