adjusted sync features

This commit is contained in:
Schnitzel5 2025-07-04 02:24:01 +02:00
parent b4da640df8
commit bd17e1e9eb
74 changed files with 1124 additions and 844 deletions

View file

@ -428,8 +428,6 @@
"sync_auto": "المزامنة التلقائية",
"sync_auto_warning": "المزامنة التلقائية هي ميزة تجريبية حاليًا!",
"sync_auto_off": "إيقاف",
"sync_auto_30_seconds": "كل 30 ثانية",
"sync_auto_1_minute": "كل دقيقة",
"sync_auto_5_minutes": "كل 5 دقائق",
"sync_auto_10_minutes": "كل 10 دقائق",
"sync_auto_30_minutes": "كل 30 دقيقة",

View file

@ -243,8 +243,6 @@
"sync_auto": "Auto Sync",
"sync_auto_warning": "Auto Sync ist derzeit ein experimentelles Feature!",
"sync_auto_off": "Aus",
"sync_auto_30_seconds": "Alle 30 Sekunden",
"sync_auto_1_minute": "Jede Minute",
"sync_auto_5_minutes": "Alle 5 Minuten",
"sync_auto_10_minutes": "Alle 10 Minuten",
"sync_auto_30_minutes": "Alle 30 Minuten",

View file

@ -244,8 +244,6 @@
"sync_auto": "Auto Sync",
"sync_auto_warning": "Auto Sync is currently an experimental feature!",
"sync_auto_off": "Off",
"sync_auto_30_seconds": "Every 30 seconds",
"sync_auto_1_minute": "Every 1 minute",
"sync_auto_5_minutes": "Every 5 minutes",
"sync_auto_10_minutes": "Every 10 minutes",
"sync_auto_30_minutes": "Every 30 minutes",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sincronización automática",
"sync_auto_warning": "¡La sincronización automática es una función experimental actualmente!",
"sync_auto_off": "Desactivado",
"sync_auto_30_seconds": "Cada 30 segundos",
"sync_auto_1_minute": "Cada 1 minuto",
"sync_auto_5_minutes": "Cada 5 minutos",
"sync_auto_10_minutes": "Cada 10 minutos",
"sync_auto_30_minutes": "Cada 30 minutos",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sincronización automática",
"sync_auto_warning": "¡La sincronización automática es una función experimental actualmente!",
"sync_auto_off": "Desactivado",
"sync_auto_30_seconds": "Cada 30 segundos",
"sync_auto_1_minute": "Cada 1 minuto",
"sync_auto_5_minutes": "Cada 5 minutos",
"sync_auto_10_minutes": "Cada 10 minutos",
"sync_auto_30_minutes": "Cada 30 minutos",

View file

@ -428,8 +428,6 @@
"sync_auto": "Synchronisation automatique",
"sync_auto_warning": "La synchronisation automatique est actuellement une fonctionnalité expérimentale !",
"sync_auto_off": "Désactivé",
"sync_auto_30_seconds": "Toutes les 30 secondes",
"sync_auto_1_minute": "Toutes les 1 minute",
"sync_auto_5_minutes": "Toutes les 5 minutes",
"sync_auto_10_minutes": "Toutes les 10 minutes",
"sync_auto_30_minutes": "Toutes les 30 minutes",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sinkronisasi otomatis",
"sync_auto_warning": "Sinkronisasi otomatis saat ini adalah fitur eksperimental!",
"sync_auto_off": "Mati",
"sync_auto_30_seconds": "Setiap 30 detik",
"sync_auto_1_minute": "Setiap 1 menit",
"sync_auto_5_minutes": "Setiap 5 menit",
"sync_auto_10_minutes": "Setiap 10 menit",
"sync_auto_30_minutes": "Setiap 30 menit",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sincronizzazione automatica",
"sync_auto_warning": "La sincronizzazione automatica è attualmente una funzione sperimentale!",
"sync_auto_off": "Disattivato",
"sync_auto_30_seconds": "Ogni 30 secondi",
"sync_auto_1_minute": "Ogni 1 minuto",
"sync_auto_5_minutes": "Ogni 5 minuti",
"sync_auto_10_minutes": "Ogni 10 minuti",
"sync_auto_30_minutes": "Ogni 30 minuti",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sincronização automática",
"sync_auto_warning": "A sincronização automática é atualmente um recurso experimental!",
"sync_auto_off": "Desativado",
"sync_auto_30_seconds": "A cada 30 segundos",
"sync_auto_1_minute": "A cada 1 minuto",
"sync_auto_5_minutes": "A cada 5 minutos",
"sync_auto_10_minutes": "A cada 10 minutos",
"sync_auto_30_minutes": "A cada 30 minutos",

View file

@ -428,8 +428,6 @@
"sync_auto": "Sincronização automática",
"sync_auto_warning": "A sincronização automática é atualmente um recurso experimental!",
"sync_auto_off": "Desativado",
"sync_auto_30_seconds": "A cada 30 segundos",
"sync_auto_1_minute": "A cada 1 minuto",
"sync_auto_5_minutes": "A cada 5 minutos",
"sync_auto_10_minutes": "A cada 10 minutos",
"sync_auto_30_minutes": "A cada 30 minutos",

View file

@ -428,8 +428,6 @@
"sync_auto": "Автосинхронизация",
"sync_auto_warning": "Автосинхронизация в настоящее время является экспериментальной функцией!",
"sync_auto_off": "Выключено",
"sync_auto_30_seconds": "Каждые 30 секунд",
"sync_auto_1_minute": "Каждую минуту",
"sync_auto_5_minutes": "Каждые 5 минут",
"sync_auto_10_minutes": "Каждые 10 минут",
"sync_auto_30_minutes": "Каждые 30 минут",

View file

@ -431,8 +431,6 @@
"sync_auto": "การซิงค์อัตโนมัติ",
"sync_auto_warning": "การซิงค์อัตโนมัติเป็นฟีเจอร์ทดลองในขณะนี้!",
"sync_auto_off": "ปิด",
"sync_auto_30_seconds": "ทุก 30 วินาที",
"sync_auto_1_minute": "ทุก 1 นาที",
"sync_auto_5_minutes": "ทุก 5 นาที",
"sync_auto_10_minutes": "ทุก 10 นาที",
"sync_auto_30_minutes": "ทุก 30 นาที",

View file

@ -428,8 +428,6 @@
"sync_auto": "Otomatik senkronizasyon",
"sync_auto_warning": "Otomatik senkronizasyon şu anda deneysel bir özelliktir!",
"sync_auto_off": "Kapalı",
"sync_auto_30_seconds": "Her 30 saniyede bir",
"sync_auto_1_minute": "Her 1 dakikada bir",
"sync_auto_5_minutes": "Her 5 dakikada bir",
"sync_auto_10_minutes": "Her 10 dakikada bir",
"sync_auto_30_minutes": "Her 30 dakikada bir",

View file

@ -433,8 +433,6 @@
"sync_auto": "自动同步",
"sync_auto_warning": "自动同步目前是实验性功能!",
"sync_auto_off": "关闭",
"sync_auto_30_seconds": "每30秒",
"sync_auto_1_minute": "每1分钟",
"sync_auto_5_minutes": "每5分钟",
"sync_auto_10_minutes": "每10分钟",
"sync_auto_30_minutes": "每30分钟",

View file

@ -12,12 +12,15 @@ class Category {
bool? hide;
@enumerated
late ItemType forItemType;
int? updatedAt;
Category({
this.id = Isar.autoIncrement,
required this.name,
required this.forItemType,
this.pos,
this.hide,
this.updatedAt = 0,
});
Category.fromJson(Map<String, dynamic> json) {
@ -26,6 +29,7 @@ class Category {
forItemType = ItemType.values[json['forItemType'] ?? 0];
pos = json['pos'];
hide = json['hide'];
updatedAt = json['updatedAt'];
}
Category.fromJsonV1(Map<String, dynamic> json) {
@ -44,5 +48,6 @@ class Category {
'forItemType': forItemType.index,
'pos': pos,
'hide': hide,
'updatedAt': updatedAt,
};
}

View file

@ -42,6 +42,11 @@ const CategorySchema = CollectionSchema(
id: 4,
name: r'pos',
type: IsarType.long,
),
r'updatedAt': PropertySchema(
id: 5,
name: r'updatedAt',
type: IsarType.long,
)
},
estimateSize: _categoryEstimateSize,
@ -84,6 +89,7 @@ void _categorySerialize(
writer.writeBool(offsets[2], object.hide);
writer.writeString(offsets[3], object.name);
writer.writeLong(offsets[4], object.pos);
writer.writeLong(offsets[5], object.updatedAt);
}
Category _categoryDeserialize(
@ -100,6 +106,7 @@ Category _categoryDeserialize(
id: id,
name: reader.readStringOrNull(offsets[3]),
pos: reader.readLongOrNull(offsets[4]),
updatedAt: reader.readLongOrNull(offsets[5]),
);
object.forManga = reader.readBoolOrNull(offsets[1]);
return object;
@ -123,6 +130,8 @@ P _categoryDeserializeProp<P>(
return (reader.readStringOrNull(offset)) as P;
case 4:
return (reader.readLongOrNull(offset)) as P;
case 5:
return (reader.readLongOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -616,6 +625,75 @@ extension CategoryQueryFilter
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Category, Category, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension CategoryQueryObject
@ -684,6 +762,18 @@ extension CategoryQuerySortBy on QueryBuilder<Category, Category, QSortBy> {
return query.addSortBy(r'pos', Sort.desc);
});
}
QueryBuilder<Category, Category, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Category, Category, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension CategoryQuerySortThenBy
@ -759,6 +849,18 @@ extension CategoryQuerySortThenBy
return query.addSortBy(r'pos', Sort.desc);
});
}
QueryBuilder<Category, Category, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Category, Category, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension CategoryQueryWhereDistinct
@ -793,6 +895,12 @@ extension CategoryQueryWhereDistinct
return query.addDistinctBy(r'pos');
});
}
QueryBuilder<Category, Category, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
}
extension CategoryQueryProperty
@ -832,4 +940,10 @@ extension CategoryQueryProperty
return query.addPropertyName(r'pos');
});
}
QueryBuilder<Category, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
}

View file

@ -28,30 +28,11 @@ class ChangedPart {
}
enum ActionType {
addItem(name: "ADD_ITEM"),
removeItem(name: "REMOVE_ITEM"),
updateItem(name: "UPDATE_ITEM"),
addCategory(name: "ADD_CATEGORY"),
removeCategory(name: "REMOVE_CATEGORY"),
renameCategory(name: "RENAME_CATEGORY"),
addChapter(name: "ADD_CHAPTER"),
removeChapter(name: "REMOVE_CHAPTER"),
updateChapter(name: "UPDATE_CHAPTER"),
clearHistory(name: "CLEAR_HISTORY"),
addHistory(name: "ADD_HISTORY"),
removeHistory(name: "REMOVE_HISTORY"),
updateHistory(name: "UPDATE_HISTORY"),
clearUpdates(name: "CLEAR_UPDATES"),
addUpdate(name: "ADD_UPDATE"),
clearExtension(name: "CLEAR_EXTENSION"),
addExtension(name: "ADD_EXTENSION"),
removeExtension(name: "REMOVE_EXTENSION"),
updateExtension(name: "UPDATE_EXTENSION"),
addTrack(name: "ADD_TRACK"),
removeTrack(name: "REMOVE_TRACK"),
updateTrack(name: "UPDATE_TRACK");
final String name;
const ActionType({required this.name});
removeItem,
removeCategory,
removeChapter,
removeHistory,
removeUpdate,
removeExtension,
removeTrack,
}

View file

@ -84,7 +84,7 @@ ChangedPart _changedPartDeserialize(
final object = ChangedPart(
actionType:
_ChangedPartactionTypeValueEnumMap[reader.readByteOrNull(offsets[0])] ??
ActionType.addItem,
ActionType.removeItem,
clientDate: reader.readLong(offsets[1]),
data: reader.readString(offsets[2]),
id: id,
@ -103,7 +103,7 @@ P _changedPartDeserializeProp<P>(
case 0:
return (_ChangedPartactionTypeValueEnumMap[
reader.readByteOrNull(offset)] ??
ActionType.addItem) as P;
ActionType.removeItem) as P;
case 1:
return (reader.readLong(offset)) as P;
case 2:
@ -116,52 +116,22 @@ P _changedPartDeserializeProp<P>(
}
const _ChangedPartactionTypeEnumValueMap = {
'addItem': 0,
'removeItem': 1,
'updateItem': 2,
'addCategory': 3,
'removeCategory': 4,
'renameCategory': 5,
'addChapter': 6,
'removeChapter': 7,
'updateChapter': 8,
'clearHistory': 9,
'addHistory': 10,
'removeHistory': 11,
'updateHistory': 12,
'clearUpdates': 13,
'addUpdate': 14,
'clearExtension': 15,
'addExtension': 16,
'removeExtension': 17,
'updateExtension': 18,
'addTrack': 19,
'removeTrack': 20,
'updateTrack': 21,
'removeItem': 0,
'removeCategory': 1,
'removeChapter': 2,
'removeHistory': 3,
'removeUpdate': 4,
'removeExtension': 5,
'removeTrack': 6,
};
const _ChangedPartactionTypeValueEnumMap = {
0: ActionType.addItem,
1: ActionType.removeItem,
2: ActionType.updateItem,
3: ActionType.addCategory,
4: ActionType.removeCategory,
5: ActionType.renameCategory,
6: ActionType.addChapter,
7: ActionType.removeChapter,
8: ActionType.updateChapter,
9: ActionType.clearHistory,
10: ActionType.addHistory,
11: ActionType.removeHistory,
12: ActionType.updateHistory,
13: ActionType.clearUpdates,
14: ActionType.addUpdate,
15: ActionType.clearExtension,
16: ActionType.addExtension,
17: ActionType.removeExtension,
18: ActionType.updateExtension,
19: ActionType.addTrack,
20: ActionType.removeTrack,
21: ActionType.updateTrack,
0: ActionType.removeItem,
1: ActionType.removeCategory,
2: ActionType.removeChapter,
3: ActionType.removeHistory,
4: ActionType.removeUpdate,
5: ActionType.removeExtension,
6: ActionType.removeTrack,
};
Id _changedPartGetId(ChangedPart object) {

View file

@ -26,6 +26,8 @@ class Chapter {
///Only for local archive Comic
String? archivePath;
int? updatedAt;
final manga = IsarLink<Manga>();
Chapter({
@ -39,6 +41,7 @@ class Chapter {
this.isRead = false,
this.lastPageRead = '',
this.archivePath = '',
this.updatedAt = 0,
});
Chapter.fromJson(Map<String, dynamic> json) {
@ -52,6 +55,7 @@ class Chapter {
name = json['name'];
scanlator = json['scanlator'];
url = json['url'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -65,5 +69,6 @@ class Chapter {
'name': name,
'scanlator': scanlator,
'url': url,
'updatedAt': updatedAt,
};
}

View file

@ -57,8 +57,13 @@ const ChapterSchema = CollectionSchema(
name: r'scanlator',
type: IsarType.string,
),
r'url': PropertySchema(
r'updatedAt': PropertySchema(
id: 8,
name: r'updatedAt',
type: IsarType.long,
),
r'url': PropertySchema(
id: 9,
name: r'url',
type: IsarType.string,
)
@ -143,7 +148,8 @@ void _chapterSerialize(
writer.writeLong(offsets[5], object.mangaId);
writer.writeString(offsets[6], object.name);
writer.writeString(offsets[7], object.scanlator);
writer.writeString(offsets[8], object.url);
writer.writeLong(offsets[8], object.updatedAt);
writer.writeString(offsets[9], object.url);
}
Chapter _chapterDeserialize(
@ -162,7 +168,8 @@ Chapter _chapterDeserialize(
mangaId: reader.readLongOrNull(offsets[5]),
name: reader.readStringOrNull(offsets[6]),
scanlator: reader.readStringOrNull(offsets[7]),
url: reader.readStringOrNull(offsets[8]),
updatedAt: reader.readLongOrNull(offsets[8]),
url: reader.readStringOrNull(offsets[9]),
);
return object;
}
@ -191,6 +198,8 @@ P _chapterDeserializeProp<P>(
case 7:
return (reader.readStringOrNull(offset)) as P;
case 8:
return (reader.readLongOrNull(offset)) as P;
case 9:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
@ -1210,6 +1219,75 @@ extension ChapterQueryFilter
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<Chapter, Chapter, QAfterFilterCondition> urlIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
@ -1473,6 +1551,18 @@ extension ChapterQuerySortBy on QueryBuilder<Chapter, Chapter, QSortBy> {
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> sortByUrl() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'url', Sort.asc);
@ -1596,6 +1686,18 @@ extension ChapterQuerySortThenBy
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
QueryBuilder<Chapter, Chapter, QAfterSortBy> thenByUrl() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'url', Sort.asc);
@ -1664,6 +1766,12 @@ extension ChapterQueryWhereDistinct
});
}
QueryBuilder<Chapter, Chapter, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
QueryBuilder<Chapter, Chapter, QDistinct> distinctByUrl(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
@ -1728,6 +1836,12 @@ extension ChapterQueryProperty
});
}
QueryBuilder<Chapter, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
QueryBuilder<Chapter, String?, QQueryOperations> urlProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'url');

View file

@ -21,6 +21,8 @@ class History {
String? date;
int? updatedAt;
History({
this.id = Isar.autoIncrement,
this.isManga,
@ -28,6 +30,7 @@ class History {
required this.chapterId,
required this.mangaId,
required this.date,
this.updatedAt = 0,
});
History.fromJson(Map<String, dynamic> json) {
@ -37,6 +40,7 @@ class History {
isManga = json['isManga'];
itemType = ItemType.values[json['itemType'] ?? 0];
mangaId = json['mangaId'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -45,5 +49,6 @@ class History {
'id': id,
'itemType': itemType.index,
'mangaId': mangaId,
'updatedAt': updatedAt,
};
}

View file

@ -42,6 +42,11 @@ const HistorySchema = CollectionSchema(
id: 4,
name: r'mangaId',
type: IsarType.long,
),
r'updatedAt': PropertySchema(
id: 5,
name: r'updatedAt',
type: IsarType.long,
)
},
estimateSize: _historyEstimateSize,
@ -91,6 +96,7 @@ void _historySerialize(
writer.writeBool(offsets[2], object.isManga);
writer.writeByte(offsets[3], object.itemType.index);
writer.writeLong(offsets[4], object.mangaId);
writer.writeLong(offsets[5], object.updatedAt);
}
History _historyDeserialize(
@ -107,6 +113,7 @@ History _historyDeserialize(
itemType: _HistoryitemTypeValueEnumMap[reader.readByteOrNull(offsets[3])] ??
ItemType.manga,
mangaId: reader.readLongOrNull(offsets[4]),
updatedAt: reader.readLongOrNull(offsets[5]),
);
return object;
}
@ -129,6 +136,8 @@ P _historyDeserializeProp<P>(
ItemType.manga) as P;
case 4:
return (reader.readLongOrNull(offset)) as P;
case 5:
return (reader.readLongOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -665,6 +674,75 @@ extension HistoryQueryFilter
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<History, History, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension HistoryQueryObject
@ -746,6 +824,18 @@ extension HistoryQuerySortBy on QueryBuilder<History, History, QSortBy> {
return query.addSortBy(r'mangaId', Sort.desc);
});
}
QueryBuilder<History, History, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<History, History, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension HistoryQuerySortThenBy
@ -821,6 +911,18 @@ extension HistoryQuerySortThenBy
return query.addSortBy(r'mangaId', Sort.desc);
});
}
QueryBuilder<History, History, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<History, History, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension HistoryQueryWhereDistinct
@ -855,6 +957,12 @@ extension HistoryQueryWhereDistinct
return query.addDistinctBy(r'mangaId');
});
}
QueryBuilder<History, History, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
}
extension HistoryQueryProperty
@ -894,4 +1002,10 @@ extension HistoryQueryProperty
return query.addPropertyName(r'mangaId');
});
}
QueryBuilder<History, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
}

View file

@ -49,6 +49,8 @@ class Manga {
String? customCoverFromTracker;
int? updatedAt;
@Backlink(to: "manga")
final chapters = IsarLinks<Chapter>();
@ -74,6 +76,7 @@ class Manga {
this.isLocalArchive = false,
this.customCoverImage,
this.customCoverFromTracker,
this.updatedAt = 0,
});
Manga.fromJson(Map<String, dynamic> json) {
@ -98,6 +101,7 @@ class Manga {
source = json['source'];
status = Status.values[json['status']];
customCoverFromTracker = json['customCoverFromTracker'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -121,6 +125,7 @@ class Manga {
'source': source,
'status': status.index,
'customCoverFromTracker': customCoverFromTracker,
'updatedAt': updatedAt,
};
}

View file

@ -118,6 +118,11 @@ const MangaSchema = CollectionSchema(
name: r'status',
type: IsarType.byte,
enumMap: _MangastatusEnumValueMap,
),
r'updatedAt': PropertySchema(
id: 20,
name: r'updatedAt',
type: IsarType.long,
)
},
estimateSize: _mangaEstimateSize,
@ -255,6 +260,7 @@ void _mangaSerialize(
writer.writeString(offsets[17], object.name);
writer.writeString(offsets[18], object.source);
writer.writeByte(offsets[19], object.status.index);
writer.writeLong(offsets[20], object.updatedAt);
}
Manga _mangaDeserialize(
@ -287,6 +293,7 @@ Manga _mangaDeserialize(
source: reader.readStringOrNull(offsets[18]),
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[19])] ??
Status.ongoing,
updatedAt: reader.readLongOrNull(offsets[20]),
);
return object;
}
@ -340,6 +347,8 @@ P _mangaDeserializeProp<P>(
case 19:
return (_MangastatusValueEnumMap[reader.readByteOrNull(offset)] ??
Status.ongoing) as P;
case 20:
return (reader.readLongOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -2779,6 +2788,75 @@ extension MangaQueryFilter on QueryBuilder<Manga, Manga, QFilterCondition> {
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Manga, Manga, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension MangaQueryObject on QueryBuilder<Manga, Manga, QFilterCondition> {}
@ -3045,6 +3123,18 @@ extension MangaQuerySortBy on QueryBuilder<Manga, Manga, QSortBy> {
return query.addSortBy(r'status', Sort.desc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension MangaQuerySortThenBy on QueryBuilder<Manga, Manga, QSortThenBy> {
@ -3263,6 +3353,18 @@ extension MangaQuerySortThenBy on QueryBuilder<Manga, Manga, QSortThenBy> {
return query.addSortBy(r'status', Sort.desc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Manga, Manga, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension MangaQueryWhereDistinct on QueryBuilder<Manga, Manga, QDistinct> {
@ -3395,6 +3497,12 @@ extension MangaQueryWhereDistinct on QueryBuilder<Manga, Manga, QDistinct> {
return query.addDistinctBy(r'status');
});
}
QueryBuilder<Manga, Manga, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
}
extension MangaQueryProperty on QueryBuilder<Manga, Manga, QQueryProperty> {
@ -3524,4 +3632,10 @@ extension MangaQueryProperty on QueryBuilder<Manga, Manga, QQueryProperty> {
return query.addPropertyName(r'status');
});
}
QueryBuilder<Manga, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
}

View file

@ -69,6 +69,8 @@ class Source {
Repo? repo;
int? updatedAt;
Source({
this.id = 0,
this.name = '',
@ -99,6 +101,7 @@ class Source {
this.isObsolete = false,
this.notes = '',
this.repo,
this.updatedAt = 0,
});
Source.fromJson(Map<String, dynamic> json) {
@ -133,6 +136,7 @@ class Source {
SourceCodeLanguage.values[json['sourceCodeLanguage'] ?? 0];
notes = json['notes'] ?? "";
repo = json['repo'] != null ? Repo.fromJson(json['repo']) : null;
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -166,6 +170,7 @@ class Source {
'isLocal': isLocal,
'notes': notes,
'repo': repo?.toJson(),
'updatedAt': updatedAt,
};
bool get isTorrent => (typeSource?.toLowerCase() ?? "") == "torrent";

View file

@ -160,13 +160,18 @@ const SourceSchema = CollectionSchema(
name: r'typeSource',
type: IsarType.string,
),
r'version': PropertySchema(
r'updatedAt': PropertySchema(
id: 28,
name: r'updatedAt',
type: IsarType.long,
),
r'version': PropertySchema(
id: 29,
name: r'version',
type: IsarType.string,
),
r'versionLast': PropertySchema(
id: 29,
id: 30,
name: r'versionLast',
type: IsarType.string,
)
@ -336,8 +341,9 @@ void _sourceSerialize(
writer.writeByte(offsets[25], object.sourceCodeLanguage.index);
writer.writeString(offsets[26], object.sourceCodeUrl);
writer.writeString(offsets[27], object.typeSource);
writer.writeString(offsets[28], object.version);
writer.writeString(offsets[29], object.versionLast);
writer.writeLong(offsets[28], object.updatedAt);
writer.writeString(offsets[29], object.version);
writer.writeString(offsets[30], object.versionLast);
}
Source _sourceDeserialize(
@ -379,8 +385,9 @@ Source _sourceDeserialize(
sourceCode: reader.readStringOrNull(offsets[24]),
sourceCodeUrl: reader.readStringOrNull(offsets[26]),
typeSource: reader.readStringOrNull(offsets[27]),
version: reader.readStringOrNull(offsets[28]),
versionLast: reader.readStringOrNull(offsets[29]),
updatedAt: reader.readLongOrNull(offsets[28]),
version: reader.readStringOrNull(offsets[29]),
versionLast: reader.readStringOrNull(offsets[30]),
);
object.sourceCodeLanguage = _SourcesourceCodeLanguageValueEnumMap[
reader.readByteOrNull(offsets[25])] ??
@ -459,9 +466,11 @@ P _sourceDeserializeProp<P>(
case 27:
return (reader.readStringOrNull(offset)) as P;
case 28:
return (reader.readStringOrNull(offset)) as P;
return (reader.readLongOrNull(offset)) as P;
case 29:
return (reader.readStringOrNull(offset)) as P;
case 30:
return (reader.readStringOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -3089,6 +3098,75 @@ extension SourceQueryFilter on QueryBuilder<Source, Source, QFilterCondition> {
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
QueryBuilder<Source, Source, QAfterFilterCondition> versionIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
@ -3718,6 +3796,18 @@ extension SourceQuerySortBy on QueryBuilder<Source, Source, QSortBy> {
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> sortByVersion() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'version', Sort.asc);
@ -4080,6 +4170,18 @@ extension SourceQuerySortThenBy on QueryBuilder<Source, Source, QSortThenBy> {
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
QueryBuilder<Source, Source, QAfterSortBy> thenByVersion() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'version', Sort.asc);
@ -4285,6 +4387,12 @@ extension SourceQueryWhereDistinct on QueryBuilder<Source, Source, QDistinct> {
});
}
QueryBuilder<Source, Source, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
QueryBuilder<Source, Source, QDistinct> distinctByVersion(
{bool caseSensitive = true}) {
return QueryBuilder.apply(this, (query) {
@ -4476,6 +4584,12 @@ extension SourceQueryProperty on QueryBuilder<Source, Source, QQueryProperty> {
});
}
QueryBuilder<Source, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
QueryBuilder<Source, String?, QQueryOperations> versionProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'version');

View file

@ -37,6 +37,8 @@ class Track {
@enumerated
late ItemType itemType;
int? updatedAt;
Track({
this.id = Isar.autoIncrement,
this.libraryId,
@ -53,6 +55,7 @@ class Track {
this.trackingUrl,
this.isManga,
this.itemType = ItemType.manga,
this.updatedAt = 0,
});
Track.fromJson(Map<String, dynamic> json) {
finishedReadingDate = json['finishedReadingDate'];
@ -69,6 +72,7 @@ class Track {
totalChapter = json['totalChapter'];
trackingUrl = json['trackingUrl'];
isManga = json['isManga'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -86,6 +90,7 @@ class Track {
'totalChapter': totalChapter,
'trackingUrl': trackingUrl,
'isManga': isManga,
'updatedAt': updatedAt,
};
}

View file

@ -88,6 +88,11 @@ const TrackSchema = CollectionSchema(
id: 13,
name: r'trackingUrl',
type: IsarType.string,
),
r'updatedAt': PropertySchema(
id: 14,
name: r'updatedAt',
type: IsarType.long,
)
},
estimateSize: _trackEstimateSize,
@ -145,6 +150,7 @@ void _trackSerialize(
writer.writeString(offsets[11], object.title);
writer.writeLong(offsets[12], object.totalChapter);
writer.writeString(offsets[13], object.trackingUrl);
writer.writeLong(offsets[14], object.updatedAt);
}
Track _trackDeserialize(
@ -171,6 +177,7 @@ Track _trackDeserialize(
title: reader.readStringOrNull(offsets[11]),
totalChapter: reader.readLongOrNull(offsets[12]),
trackingUrl: reader.readStringOrNull(offsets[13]),
updatedAt: reader.readLongOrNull(offsets[14]),
);
return object;
}
@ -212,6 +219,8 @@ P _trackDeserializeProp<P>(
return (reader.readLongOrNull(offset)) as P;
case 13:
return (reader.readStringOrNull(offset)) as P;
case 14:
return (reader.readLongOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -1449,6 +1458,75 @@ extension TrackQueryFilter on QueryBuilder<Track, Track, QFilterCondition> {
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Track, Track, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension TrackQueryObject on QueryBuilder<Track, Track, QFilterCondition> {}
@ -1623,6 +1701,18 @@ extension TrackQuerySortBy on QueryBuilder<Track, Track, QSortBy> {
return query.addSortBy(r'trackingUrl', Sort.desc);
});
}
QueryBuilder<Track, Track, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Track, Track, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension TrackQuerySortThenBy on QueryBuilder<Track, Track, QSortThenBy> {
@ -1805,6 +1895,18 @@ extension TrackQuerySortThenBy on QueryBuilder<Track, Track, QSortThenBy> {
return query.addSortBy(r'trackingUrl', Sort.desc);
});
}
QueryBuilder<Track, Track, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Track, Track, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension TrackQueryWhereDistinct on QueryBuilder<Track, Track, QDistinct> {
@ -1893,6 +1995,12 @@ extension TrackQueryWhereDistinct on QueryBuilder<Track, Track, QDistinct> {
return query.addDistinctBy(r'trackingUrl', caseSensitive: caseSensitive);
});
}
QueryBuilder<Track, Track, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
}
extension TrackQueryProperty on QueryBuilder<Track, Track, QQueryProperty> {
@ -1985,4 +2093,10 @@ extension TrackQueryProperty on QueryBuilder<Track, Track, QQueryProperty> {
return query.addPropertyName(r'trackingUrl');
});
}
QueryBuilder<Track, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
}

View file

@ -15,11 +15,14 @@ class Update {
String? date;
int? updatedAt;
Update({
this.id = Isar.autoIncrement,
required this.mangaId,
required this.chapterName,
required this.date,
this.updatedAt = 0,
});
Update.fromJson(Map<String, dynamic> json) {
@ -27,6 +30,7 @@ class Update {
mangaId = json['mangaId'];
chapterName = json['chapterName'];
date = json['date'];
updatedAt = json['updatedAt'];
}
Map<String, dynamic> toJson() => {
@ -34,5 +38,6 @@ class Update {
'mangaId': mangaId,
'chapterName': chapterName,
'date': date,
'updatedAt': updatedAt,
};
}

View file

@ -31,6 +31,11 @@ const UpdateSchema = CollectionSchema(
id: 2,
name: r'mangaId',
type: IsarType.long,
),
r'updatedAt': PropertySchema(
id: 3,
name: r'updatedAt',
type: IsarType.long,
)
},
estimateSize: _updateEstimateSize,
@ -84,6 +89,7 @@ void _updateSerialize(
writer.writeString(offsets[0], object.chapterName);
writer.writeString(offsets[1], object.date);
writer.writeLong(offsets[2], object.mangaId);
writer.writeLong(offsets[3], object.updatedAt);
}
Update _updateDeserialize(
@ -97,6 +103,7 @@ Update _updateDeserialize(
date: reader.readStringOrNull(offsets[1]),
id: id,
mangaId: reader.readLongOrNull(offsets[2]),
updatedAt: reader.readLongOrNull(offsets[3]),
);
return object;
}
@ -114,6 +121,8 @@ P _updateDeserializeProp<P>(
return (reader.readStringOrNull(offset)) as P;
case 2:
return (reader.readLongOrNull(offset)) as P;
case 3:
return (reader.readLongOrNull(offset)) as P;
default:
throw IsarError('Unknown property with id $propertyId');
}
@ -635,6 +644,75 @@ extension UpdateQueryFilter on QueryBuilder<Update, Update, QFilterCondition> {
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtIsNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtIsNotNull() {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(const FilterCondition.isNotNull(
property: r'updatedAt',
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtEqualTo(
int? value) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.equalTo(
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtGreaterThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.greaterThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtLessThan(
int? value, {
bool include = false,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.lessThan(
include: include,
property: r'updatedAt',
value: value,
));
});
}
QueryBuilder<Update, Update, QAfterFilterCondition> updatedAtBetween(
int? lower,
int? upper, {
bool includeLower = true,
bool includeUpper = true,
}) {
return QueryBuilder.apply(this, (query) {
return query.addFilterCondition(FilterCondition.between(
property: r'updatedAt',
lower: lower,
includeLower: includeLower,
upper: upper,
includeUpper: includeUpper,
));
});
}
}
extension UpdateQueryObject on QueryBuilder<Update, Update, QFilterCondition> {}
@ -690,6 +768,18 @@ extension UpdateQuerySortBy on QueryBuilder<Update, Update, QSortBy> {
return query.addSortBy(r'mangaId', Sort.desc);
});
}
QueryBuilder<Update, Update, QAfterSortBy> sortByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Update, Update, QAfterSortBy> sortByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension UpdateQuerySortThenBy on QueryBuilder<Update, Update, QSortThenBy> {
@ -740,6 +830,18 @@ extension UpdateQuerySortThenBy on QueryBuilder<Update, Update, QSortThenBy> {
return query.addSortBy(r'mangaId', Sort.desc);
});
}
QueryBuilder<Update, Update, QAfterSortBy> thenByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.asc);
});
}
QueryBuilder<Update, Update, QAfterSortBy> thenByUpdatedAtDesc() {
return QueryBuilder.apply(this, (query) {
return query.addSortBy(r'updatedAt', Sort.desc);
});
}
}
extension UpdateQueryWhereDistinct on QueryBuilder<Update, Update, QDistinct> {
@ -762,6 +864,12 @@ extension UpdateQueryWhereDistinct on QueryBuilder<Update, Update, QDistinct> {
return query.addDistinctBy(r'mangaId');
});
}
QueryBuilder<Update, Update, QDistinct> distinctByUpdatedAt() {
return QueryBuilder.apply(this, (query) {
return query.addDistinctBy(r'updatedAt');
});
}
}
extension UpdateQueryProperty on QueryBuilder<Update, Update, QQueryProperty> {
@ -788,4 +896,10 @@ extension UpdateQueryProperty on QueryBuilder<Update, Update, QQueryProperty> {
return query.addPropertyName(r'mangaId');
});
}
QueryBuilder<Update, int?, QQueryOperations> updatedAtProperty() {
return QueryBuilder.apply(this, (query) {
return query.addPropertyName(r'updatedAt');
});
}
}

View file

@ -1393,21 +1393,11 @@ class _AnimeStreamPageState extends riv.ConsumerState<AnimeStreamPage>
isar.writeTxnSync(() {
isar.mangas.putSync(
manga
..updatedAt = DateTime.now()
.millisecondsSinceEpoch
..customCoverImage =
imageBytes,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
if (context.mounted) {
Navigator.pop(context, "ok");

View file

@ -1,7 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/models/manga.dart';
@ -9,7 +8,6 @@ import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/player/providers/player_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/aniskip.dart';
import 'package:mangayomi/utils/chapter_recognition.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@ -127,15 +125,8 @@ class AnimeStreamController extends _$AnimeStreamController {
isar.writeTxnSync(() {
Manga? anime = episode.manga.value;
anime!.lastRead = DateTime.now().millisecondsSinceEpoch;
anime.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(anime);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
anime.id,
anime.toJson(),
false,
);
});
History? history;
@ -150,6 +141,7 @@ class AnimeStreamController extends _$AnimeStreamController {
date: DateTime.now().millisecondsSinceEpoch.toString(),
itemType: getAnime().itemType,
chapterId: episode.id,
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..chapter.value = episode;
} else {
history =
@ -159,30 +151,12 @@ class AnimeStreamController extends _$AnimeStreamController {
.findFirstSync())!
..chapterId = episode.id
..chapter.value = episode
..date = DateTime.now().millisecondsSinceEpoch.toString();
..date = DateTime.now().millisecondsSinceEpoch.toString()
..updatedAt = DateTime.now().millisecondsSinceEpoch;
}
isar.writeTxnSync(() {
isar.historys.putSync(history!);
history.chapter.saveSync();
if (empty) {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addHistory,
null,
history.toJson(),
false,
);
} else {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateHistory,
history.id,
history.toJson(),
false,
);
}
});
}
@ -206,15 +180,8 @@ class AnimeStreamController extends _$AnimeStreamController {
isar.writeTxnSync(() {
ep.isRead = isWatch;
ep.lastPageRead = (duration.inMilliseconds).toString();
ep.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(ep);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
ep.id,
ep.toJson(),
false,
);
});
if (isWatch) {
episode.updateTrackChapterRead(ref);

View file

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

View file

@ -3,12 +3,10 @@ import 'package:json_view/json_view.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/lib.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/manga/home/widget/filter_widget.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/app_font_family.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/services/get_detail.dart';
import 'package:mangayomi/services/get_filter_list.dart';
@ -153,15 +151,9 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
leading: BackButton(
onPressed: () {
isar.writeTxnSync(() {
isar.sources.putSync(source!);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
source!.id,
source!.toJson(),
false,
);
isar.sources.putSync(
source!..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
});
Navigator.pop(context, source);
},
@ -194,15 +186,11 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
source?.sourceCode = _controller.text;
if (source != null && context.mounted) {
isar.writeTxnSync(() {
isar.sources.putSync(source!);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
source!.id,
source!.toJson(),
false,
);
isar.sources.putSync(
source!
..updatedAt =
DateTime.now().millisecondsSinceEpoch,
);
});
}
},
@ -306,19 +294,11 @@ class _CodeEditorPageState extends ConsumerState<CodeEditorPage> {
source?.sourceCode = _controller.text;
if (source != null && context.mounted) {
isar.writeTxnSync(() {
isar.sources.putSync(source!);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateExtension,
source!.id,
source!.toJson(),
false,
);
isar.sources.putSync(
source!
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
});
}
setState(() {

View file

@ -302,20 +302,10 @@ class _ExtensionDetailState extends ConsumerState<ExtensionDetail> {
widget.source
..sourceCode = ""
..isAdded = false
..isPinned = false,
..isPinned = false
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
}
isar.sourcePreferences.deleteAllSync(
sourcePrefsIds,

View file

@ -2,10 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/modules/browse/extension/widgets/extension_lang_list_tile_widget.dart';
import 'package:mangayomi/utils/global_style.dart';
@ -44,15 +42,11 @@ class ExtensionsLang extends ConsumerWidget {
.itemTypeEqualTo(itemType)
.findAllSync();
for (var source in sources) {
isar.sources.putSync(source..isActive = enable);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
isar.sources.putSync(
source
..isActive = enable
..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
}
});
},
@ -81,15 +75,11 @@ class ExtensionsLang extends ConsumerWidget {
isar.writeTxnSync(() {
for (var source in entries) {
if (source.lang!.toLowerCase() == lang.toLowerCase()) {
isar.sources.putSync(source..isActive = val);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
isar.sources.putSync(
source
..isActive = val
..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
}
}
});

View file

@ -2,10 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -233,15 +231,11 @@ class _CreateExtensionState extends State<CreateExtension> {
? _dartTemplate
: _jsSample(source);
isar.writeTxnSync(() {
isar.sources.putSync(source);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addExtension,
source.id,
source.toJson(),
false,
);
isar.sources.putSync(
source
..updatedAt =
DateTime.now().millisecondsSinceEpoch,
);
});
Navigator.pop(context);
botToast("Source created successfully");

View file

@ -3,10 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/language.dart';
@ -56,18 +54,11 @@ class SourcesFilterScreen extends ConsumerWidget {
if (source.lang!.toLowerCase() ==
groupByValue) {
isar.sources.putSync(
source..isActive = val == true,
source
..isActive = val == true
..updatedAt =
DateTime.now().millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(syncId: 1).notifier,
)
.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
}
}
});
@ -119,15 +110,12 @@ class SourcesFilterScreen extends ConsumerWidget {
),
onChanged: (bool? value) {
isar.writeTxnSync(() {
isar.sources.putSync(element..isAdded = value);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
element.id,
element.toJson(),
false,
);
isar.sources.putSync(
element
..isAdded = value
..updatedAt =
DateTime.now().millisecondsSinceEpoch,
);
});
},
value: element.isAdded!,

View file

@ -3,10 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/cached_network.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -35,16 +33,10 @@ class SourceListTile extends StatelessWidget {
isar.writeTxnSync(() {
for (var src in sources) {
isar.sources.putSync(
src..lastUsed = src.id == source.id ? true : false,
src
..lastUsed = src.id == source.id ? true : false
..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
src.id,
src.toJson(),
false,
);
}
});
context.push('/mangaHome', extra: (source, false));
@ -109,17 +101,11 @@ class SourceListTile extends StatelessWidget {
onPressed: () {
isar.writeTxnSync(
() => isar.sources.putSync(
source..isPinned = !source.isPinned!,
source
..isPinned = !source.isPinned!
..updatedAt = DateTime.now().millisecondsSinceEpoch,
),
);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
},
icon: Icon(
Icons.push_pin_outlined,

View file

@ -475,12 +475,23 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
await isar.historys.delete(deleteId!);
for (var chapter in chapters) {
await isar.chapters.delete(chapter.id!);
await ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPartAsync(
ActionType.removeChapter,
chapter.id,
"{}",
false,
);
}
await isar.mangas.delete(manga.id!);
await ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPartAsync(ActionType.removeHistory, deleteId, "{}", false);
await ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPartAsync(ActionType.removeItem, manga.id, "{}", false);
});
await ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPartAsync(ActionType.removeItem, manga.id, "{}", true);
if (context.mounted) {
Navigator.pop(context);
}

View file

@ -1152,46 +1152,58 @@ class _LibraryScreenState extends ConsumerState<LibraryScreen>
isar.writeTxnSync(() {
for (var manga in mangasList) {
if (manga.isLocalArchive ?? false) {
final provider = ref.read(
synchingProvider(syncId: 1).notifier,
);
final histories = isar.historys
.filter()
.mangaIdEqualTo(manga.id)
.findAllSync();
for (var history in histories) {
isar.historys.deleteSync(history.id!);
provider.addChangedPart(
ActionType.removeHistory,
history.id,
"{}",
false,
);
}
for (var chapter in manga.chapters) {
isar.updates
final updates = isar.updates
.filter()
.mangaIdEqualTo(chapter.mangaId)
.chapterNameEqualTo(chapter.name)
.deleteAllSync();
isar.chapters.deleteSync(chapter.id!);
}
isar.mangas.deleteSync(manga.id!);
ref
.read(
synchingProvider(syncId: 1).notifier,
)
.addChangedPart(
ActionType.removeItem,
manga.id,
.findAllSync();
for (var update in updates) {
isar.updates.deleteSync(update.id!);
provider.addChangedPart(
ActionType.removeUpdate,
update.id,
"{}",
false,
);
}
isar.chapters.deleteSync(chapter.id!);
provider.addChangedPart(
ActionType.removeChapter,
chapter.id,
"{}",
false,
);
}
isar.mangas.deleteSync(manga.id!);
provider.addChangedPart(
ActionType.removeItem,
manga.id,
"{}",
false,
);
} else {
manga.favorite = false;
manga.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(manga);
ref
.read(
synchingProvider(syncId: 1).notifier,
)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
}
}
});

View file

@ -1,9 +1,7 @@
import 'package:file_picker/file_picker.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/torrent_server.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -52,28 +50,21 @@ Future addTorrentFromUrlOrFromFile(
description: '',
isLocalArchive: true,
artist: '',
updatedAt: dateNow,
);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.addItem, null, manga.toJson(), true);
if (url != null) {
manga.customCoverImage = null;
isar.writeTxnSync(() {
isar.mangas.putSync(manga);
final chapters = Chapter(name: torrentName, url: url, mangaId: manga.id)
..manga.value = manga;
final chapters = Chapter(
name: torrentName,
url: url,
mangaId: manga.id,
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..manga.value = manga;
isar.chapters.putSync(chapters);
chapters.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addChapter,
null,
chapters.toJson(),
false,
);
});
} else {
for (var file in result!.files.reversed.toList()) {
@ -89,17 +80,10 @@ Future addTorrentFromUrlOrFromFile(
name: name,
archivePath: file.path,
mangaId: manga.id,
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..manga.value = manga;
isar.chapters.putSync(chapters);
chapters.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addChapter,
null,
chapters.toJson(),
false,
);
});
}
}

View file

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

View file

@ -1,11 +1,9 @@
import 'package:flutter/material.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'library_state_provider.g.dart';
@ -817,16 +815,9 @@ class MangasSetIsReadState extends _$MangasSetIsReadState {
for (var chapter in chapters) {
chapter.isRead = true;
chapter.lastPageRead = "1";
chapter.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
}
@ -849,16 +840,9 @@ class MangasSetUnReadState extends _$MangasSetUnReadState {
isar.writeTxnSync(() {
for (var chapter in chapters) {
chapter.isRead = false;
chapter.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
}

View file

@ -2551,7 +2551,7 @@ final isLongPressedMangaStateProvider =
typedef _$IsLongPressedMangaState = AutoDisposeNotifier<bool>;
String _$mangasSetIsReadStateHash() =>
r'b599664aed8cc00d35a683fa6660bf79b66c555d';
r'a973367ebc8a41ae36c1c5fc012755b13de81dc6';
abstract class _$MangasSetIsReadState
extends BuildlessAutoDisposeNotifier<void> {
@ -2698,7 +2698,7 @@ class _MangasSetIsReadStateProviderElement
}
String _$mangasSetUnReadStateHash() =>
r'03906113f5e5878909a5a6399ead997eaa2c1204';
r'2e8f4f0eaf916c2e51013be08a943999fa554ae6';
abstract class _$MangasSetUnReadState
extends BuildlessAutoDisposeNotifier<void> {

View file

@ -1,12 +1,10 @@
import 'dart:typed_data';
import 'package:file_picker/file_picker.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/manga/archive_reader/models/models.dart';
import 'package:mangayomi/modules/manga/archive_reader/providers/archive_reader_providers.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
part 'local_archive.g.dart';
@ -45,12 +43,9 @@ Future importArchivesFromFile(
description: '',
isLocalArchive: true,
artist: '',
updatedAt: dateNow,
);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.addItem, null, manga.toJson(), true);
for (var file in result.files.reversed.toList()) {
(String, LocalExtensionType, Uint8List, String)? data =
itemType == ItemType.manga
@ -68,17 +63,10 @@ Future importArchivesFromFile(
name: itemType == ItemType.manga ? data!.$1 : name,
archivePath: itemType == ItemType.manga ? data!.$4 : file.path,
mangaId: manga.id,
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..manga.value = manga;
isar.chapters.putSync(chapters);
chapters.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addChapter,
null,
chapters.toJson(),
false,
);
});
}
}

View file

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

View file

@ -10,7 +10,6 @@ import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/manga.dart';
@ -24,7 +23,6 @@ import 'package:mangayomi/modules/manga/detail/widgets/tracker_search_widget.dar
import 'package:mangayomi/modules/manga/detail/widgets/tracker_widget.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/pure_black_dark_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/track/widgets/track_listile.dart';
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
@ -857,18 +855,12 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
isar.writeTxnSync(() {
for (var chapter in chapters) {
chapter.isBookmarked = !chapter.isBookmarked!;
chapter.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(
chapter..manga.value = widget.manga,
);
chapter.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
ref
@ -906,6 +898,8 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (!chapter.isRead!) {
chapter.lastPageRead = "1";
}
chapter.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(
chapter..manga.value = widget.manga,
);
@ -913,14 +907,6 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (chapter.isRead!) {
chapter.updateTrackChapterRead(ref);
}
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
ref
@ -963,20 +949,12 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
if (!chapters[i].isRead!) {
chapters[i].isRead = true;
chapters[i].lastPageRead = "1";
chapters[i].updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(
chapters[i]..manga.value = widget.manga,
);
chapters[i].manga.saveSync();
ref
.read(
synchingProvider(syncId: 1).notifier,
)
.addChangedPart(
ActionType.updateChapter,
chapters[i].id,
chapters[i].toJson(),
false,
);
}
}
ref
@ -2003,20 +1981,10 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
widget.manga!
..customCoverImage = null
..customCoverFromTracker =
trackSearch.coverUrl,
trackSearch.coverUrl
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateItem,
widget.manga!.id,
widget.manga!.toJson(),
false,
);
});
if (context.mounted) {
Navigator.pop(context);
@ -2158,20 +2126,10 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
isar.mangas.putSync(
manga
..customCoverImage = null
..customCoverFromTracker = null,
..customCoverFromTracker = null
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
Navigator.pop(context);
} else if (value == 1) {
@ -2194,20 +2152,10 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
isar.mangas.putSync(
manga
..customCoverImage =
customCoverImage,
customCoverImage
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
botToast(
context.l10n.cover_updated,
@ -2311,15 +2259,8 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
final manga = widget.manga!;
manga.description = description.text;
manga.name = name.text;
manga.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
Navigator.pop(context);
},

View file

@ -3,12 +3,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/history.dart';
import 'package:mangayomi/modules/manga/detail/widgets/custom_floating_action_btn.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/category_selection_dialog.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -205,15 +203,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
isar.writeTxnSync(() {
model.favorite = false;
model.dateAdded = 0;
model.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(model);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
model.id,
model.toJson(),
false,
);
});
},
child: Column(
@ -253,22 +244,8 @@ class _MangaDetailsViewState extends ConsumerState<MangaDetailsView> {
isar.writeTxnSync(() {
model.favorite = true;
model.dateAdded = DateTime.now().millisecondsSinceEpoch;
model.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(model);
final sync = ref.read(
synchingProvider(syncId: 1).notifier,
);
sync.addChangedPart(
ActionType.addItem,
null,
model.toJson(),
false,
);
sync.addChangedPart(
ActionType.updateItem,
model.id,
model.toJson(),
false,
);
});
}
},

View file

@ -1,12 +1,10 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/modules/manga/download/providers/download_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'state_providers.g.dart';
@ -304,16 +302,9 @@ class ChapterSetIsBookmarkState extends _$ChapterSetIsBookmarkState {
isar.writeTxnSync(() {
for (var chapter in chapters) {
chapter.isBookmarked = !chapter.isBookmarked!;
chapter.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
ref.read(isLongPressedStateProvider.notifier).update(false);
@ -331,16 +322,9 @@ class ChapterSetIsReadState extends _$ChapterSetIsReadState {
isar.writeTxnSync(() {
for (var chapter in chapters) {
chapter.isRead = !chapter.isRead!;
chapter.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chapter..manga.value = manga);
chapter.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
}
});
ref.read(isLongPressedStateProvider.notifier).update(false);

View file

@ -816,7 +816,7 @@ class _ChapterFilterResultStateProviderElement
}
String _$chapterSetIsBookmarkStateHash() =>
r'9b4359e87f6083323cc49d20bedde0ce0f61d9b3';
r'7879f0a8052b1e46d32d5aaad43d1efa14bcb19d';
abstract class _$ChapterSetIsBookmarkState
extends BuildlessAutoDisposeNotifier<void> {
@ -963,7 +963,7 @@ class _ChapterSetIsBookmarkStateProviderElement
}
String _$chapterSetIsReadStateHash() =>
r'9cfd45df3f359a43140c023a584b52f8c81cbace';
r'80eae3d196cf0932c1e61bae37aebe563d66d6de';
abstract class _$ChapterSetIsReadState
extends BuildlessAutoDisposeNotifier<void> {

View file

@ -1,11 +1,9 @@
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.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';
import 'package:mangayomi/utils/utils.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@ -57,21 +55,14 @@ Future<dynamic> updateMangaDetail(
..source = manga.source
..lang = manga.lang
..itemType = source.itemType
..lastUpdate = DateTime.now().millisecondsSinceEpoch;
..lastUpdate = DateTime.now().millisecondsSinceEpoch
..updatedAt = DateTime.now().millisecondsSinceEpoch;
final checkManga = isar.mangas.getSync(mangaId);
if (checkManga!.chapters.isNotEmpty && isInit) {
return;
}
isar.writeTxnSync(() {
isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
manga.lastUpdate = DateTime.now().millisecondsSinceEpoch;
List<Chapter> chapters = [];
@ -89,6 +80,7 @@ Future<dynamic> updateMangaDetail(
: chaps[i].dateUpload.toString(),
scanlator: chaps[i].scanlator ?? '',
mangaId: mangaId,
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..manga.value = manga;
chapters.add(chapter);
}
@ -97,30 +89,15 @@ Future<dynamic> updateMangaDetail(
for (var chap in chapters.reversed.toList()) {
isar.chapters.putSync(chap);
chap.manga.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addChapter,
chap.id,
chap.toJson(),
false,
);
if (manga.chapters.isNotEmpty) {
final update = Update(
mangaId: mangaId,
chapterName: chap.name,
date: DateTime.now().millisecondsSinceEpoch.toString(),
updatedAt: DateTime.now().millisecondsSinceEpoch,
)..chapter.value = chap;
isar.updates.putSync(update);
update.chapter.saveSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addUpdate,
update.id,
update.toJson(),
false,
);
}
}
}
@ -134,33 +111,12 @@ Future<dynamic> updateMangaDetail(
for (var i = 0; i < oldChapers.length; i++) {
final oldChap = oldChapers[i];
final newChap = chaps[i];
final hasChanged =
oldChap.name != newChap.name ||
oldChap.url != newChap.url ||
oldChap.scanlator != newChap.scanlator;
oldChap.name = newChap.name;
oldChap.url = newChap.url;
oldChap.scanlator = newChap.scanlator;
oldChap.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(oldChap);
oldChap.manga.saveSync();
if (hasChanged) {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
oldChap.id,
oldChap.toJson(),
false,
);
}
}
}
});

View file

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

View file

@ -571,18 +571,11 @@ class _MigrationMangaGlobalImageCardState
favorite: true,
categories: categoryIds,
dateAdded: DateTime.now().millisecondsSinceEpoch,
updatedAt: DateTime.now().millisecondsSinceEpoch,
);
int mangaId = -1;
isar.writeTxnSync(() {
mangaId = isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addItem,
manga.id,
manga.toJson(),
false,
);
});
if (mangaId != -1) {
await ref
@ -659,15 +652,8 @@ class _MigrationMangaGlobalImageCardState
widget.oldManga.status = preview.status ?? widget.oldManga.status;
widget.oldManga.description = preview.description;
widget.oldManga.genre = preview.genre;
widget.oldManga.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(widget.oldManga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
widget.oldManga.id,
widget.oldManga.toJson(),
false,
);
});
await ref.read(
updateMangaDetailProvider(

View file

@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/download.dart';
import 'package:mangayomi/models/history.dart';
@ -12,7 +11,6 @@ import 'package:mangayomi/models/track.dart';
import 'package:mangayomi/models/track_preference.dart';
import 'package:mangayomi/modules/manga/detail/providers/track_state_providers.dart';
import 'package:mangayomi/modules/more/providers/incognito_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/more/settings/track/providers/track_providers.dart';
import 'package:mangayomi/utils/chapter_recognition.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@ -179,15 +177,8 @@ class ReaderController extends _$ReaderController {
isar.writeTxnSync(() {
Manga? manga = chapter.manga.value;
manga!.lastRead = DateTime.now().millisecondsSinceEpoch;
manga.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
History? history;
@ -214,27 +205,9 @@ class ReaderController extends _$ReaderController {
..date = DateTime.now().millisecondsSinceEpoch.toString();
}
isar.writeTxnSync(() {
isar.historys.putSync(history!);
history!.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.historys.putSync(history);
history.chapter.saveSync();
if (empty) {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addHistory,
null,
history.toJson(),
false,
);
} else {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateHistory,
history.id,
history.toJson(),
false,
);
}
});
}
@ -244,15 +217,8 @@ class ReaderController extends _$ReaderController {
final chap = chapter;
isar.writeTxnSync(() {
chap.isBookmarked = !isBookmarked;
chap.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chap);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
});
}
@ -392,15 +358,8 @@ class ReaderController extends _$ReaderController {
);
chap.isRead = isRead;
chap.lastPageRead = isRead ? '1' : (newIndex + 1).toString();
chap.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chap);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
});
if (isRead) {
chapter.updateTrackChapterRead(ref);

View file

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

View file

@ -11,7 +11,6 @@ import 'package:go_router/go_router.dart';
import 'package:mangayomi/eval/model/m_bridge.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/models/changed.dart' as changed;
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/page.dart';
import 'package:mangayomi/models/settings.dart';
@ -22,7 +21,6 @@ import 'package:mangayomi/modules/manga/reader/double_columm_view_center.dart';
import 'package:mangayomi/modules/manga/reader/providers/color_filter_provider.dart';
import 'package:mangayomi/modules/manga/reader/widgets/color_filter_widget.dart';
import 'package:mangayomi/modules/more/settings/reader/providers/reader_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/custom_draggable_tabbar.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/providers/storage_provider.dart';
@ -351,22 +349,10 @@ class _MangaChapterPageGalleryState
isar.mangas.putSync(
manga
..customCoverImage =
imageBytes,
imageBytes
..updatedAt = DateTime.now()
.millisecondsSinceEpoch,
);
ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPart(
changed
.ActionType
.updateItem,
manga.id,
manga.toJson(),
false,
);
});
if (mounted) {
Navigator.pop(context, "ok");

View file

@ -1,11 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
import 'package:mangayomi/modules/manga/reader/providers/reader_controller_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/utils/date.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
@ -188,15 +186,11 @@ class _ChapterListTileState extends State<ChapterListTile> {
});
isar.writeTxnSync(
() => {
isar.chapters.putSync(chapter..isBookmarked = isBookmarked),
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
),
isar.chapters.putSync(
chapter
..isBookmarked = isBookmarked
..updatedAt = DateTime.now().millisecondsSinceEpoch,
),
},
);
},

View file

@ -236,18 +236,10 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
onPressed: () {
isar.writeTxnSync(() async {
category.hide = !(category.hide ?? false);
category.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.categorys.putSync(category);
});
ref
.read(
synchingProvider(syncId: 1).notifier,
)
.addChangedPartAsync(
ActionType.renameCategory,
category.id,
category.toJson(),
true,
);
},
icon: Icon(
!(category.hide ?? false)
@ -394,6 +386,8 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
final category = Category(
forItemType: widget.itemType,
name: controller.text,
updatedAt: DateTime.now()
.millisecondsSinceEpoch,
);
isar.writeTxnSync(() {
isar.categorys.putSync(
@ -410,18 +404,6 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
}
});
await ref
.read(
synchingProvider(
syncId: 1,
).notifier,
)
.addChangedPartAsync(
ActionType.addCategory,
category.id,
category.toJson(),
true,
);
if (context.mounted) {
Navigator.pop(context);
}
@ -540,16 +522,10 @@ class _CategoriesTabState extends ConsumerState<CategoriesTab> {
: () async {
await isar.writeTxn(() async {
category.name = controller.text;
category.updatedAt =
DateTime.now().millisecondsSinceEpoch;
await isar.categorys.put(category);
});
await ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPartAsync(
ActionType.renameCategory,
category.id,
category.toJson(),
true,
);
if (context.mounted) {
Navigator.pop(context);
}

View file

@ -226,14 +226,6 @@ void _showClearAllSourcesDialog(BuildContext context, dynamic l10n) {
onPressed: () {
isar.writeTxnSync(() {
isar.sources.clearSync();
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.clearHistory,
null,
"{}",
false,
);
});
Navigator.pop(ctx);
@ -275,6 +267,9 @@ void _showCleanNonLibraryDialog(BuildContext context, dynamic l10n) {
.filter()
.favoriteEqualTo(false)
.findAllSync();
final provider = ref.read(
synchingProvider(syncId: 1).notifier,
);
isar.writeTxnSync(() {
for (var manga in mangasList) {
final histories = isar.historys
@ -283,25 +278,44 @@ void _showCleanNonLibraryDialog(BuildContext context, dynamic l10n) {
.findAllSync();
for (var history in histories) {
isar.historys.deleteSync(history.id!);
provider.addChangedPart(
ActionType.removeHistory,
history.id,
"{}",
false,
);
}
for (var chapter in manga.chapters) {
isar.updates
final updates = isar.updates
.filter()
.mangaIdEqualTo(chapter.mangaId)
.chapterNameEqualTo(chapter.name)
.deleteAllSync();
isar.chapters.deleteSync(chapter.id!);
}
isar.mangas.deleteSync(manga.id!);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.removeItem,
manga.id,
.findAllSync();
for (var update in updates) {
isar.updates.deleteSync(update.id!);
provider.addChangedPart(
ActionType.removeUpdate,
update.id,
"{}",
false,
);
}
isar.chapters.deleteSync(chapter.id!);
provider.addChangedPart(
ActionType.removeChapter,
chapter.id,
"{}",
false,
);
}
isar.mangas.deleteSync(manga.id!);
provider.addChangedPart(
ActionType.removeItem,
manga.id,
"{}",
false,
);
}
});

View file

@ -25,8 +25,6 @@ class SyncScreen extends ConsumerWidget {
final l10n = l10nLocalizations(context)!;
final autoSyncOptions = {
l10n.sync_auto_off: 0,
l10n.sync_auto_30_seconds: 30,
l10n.sync_auto_1_minute: 60,
l10n.sync_auto_5_minutes: 300,
l10n.sync_auto_10_minutes: 600,
l10n.sync_auto_30_minutes: 1800,
@ -542,66 +540,37 @@ class SyncScreen extends ConsumerWidget {
const SizedBox(height: 40),
buildChangedItemWidget(
l10n.sync_pending_manga,
changedParts.getChangedParts([
ActionType.addItem,
ActionType.removeItem,
ActionType.updateItem,
]),
changedParts.getChangedParts([ActionType.removeItem]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_chapter,
changedParts.getChangedParts([
ActionType.addChapter,
ActionType.removeChapter,
ActionType.updateChapter,
]),
changedParts.getChangedParts([ActionType.removeChapter]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_category,
changedParts.getChangedParts([
ActionType.addCategory,
ActionType.removeCategory,
ActionType.renameCategory,
]),
changedParts.getChangedParts([ActionType.removeCategory]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_history,
changedParts.getChangedParts([
ActionType.addHistory,
ActionType.clearHistory,
ActionType.removeHistory,
ActionType.updateHistory,
]),
changedParts.getChangedParts([ActionType.removeHistory]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_update,
changedParts.getChangedParts([
ActionType.addUpdate,
ActionType.clearUpdates,
]),
changedParts.getChangedParts([ActionType.removeUpdate]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_extension,
changedParts.getChangedParts([
ActionType.addExtension,
ActionType.clearExtension,
ActionType.removeExtension,
ActionType.updateExtension,
]),
changedParts.getChangedParts([ActionType.removeExtension]),
),
const SizedBox(height: 15),
buildChangedItemWidget(
l10n.sync_pending_track,
changedParts.getChangedParts([
ActionType.addTrack,
ActionType.removeTrack,
ActionType.updateTrack,
]),
changedParts.getChangedParts([ActionType.removeTrack]),
),
const SizedBox(height: 20),
Padding(

View file

@ -44,22 +44,9 @@ class Tracks extends _$Tracks {
isar.tracks.putSync(
track
..syncId = syncId
..itemType = itemType,
..itemType = itemType
..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
if (tra.isEmpty) {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.addTrack, null, track.toJson(), false);
} else {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateTrack,
track.id,
track.toJson(),
false,
);
}
});
}

View file

@ -6,7 +6,7 @@ part of 'track_providers.dart';
// RiverpodGenerator
// **************************************************************************
String _$tracksHash() => r'de3a19fc6542e0f610d154978fbd0272259142fc';
String _$tracksHash() => r'71db9b803345d0b31c8efba0538a68fea356a71f';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,12 +1,10 @@
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/chapter.dart';
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/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'novel_reader_controller_provider.g.dart';
@ -34,15 +32,8 @@ class NovelReaderController extends _$NovelReaderController {
isar.writeTxnSync(() {
Manga? manga = chapter.manga.value;
manga!.lastRead = DateTime.now().millisecondsSinceEpoch;
manga.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
manga.id,
manga.toJson(),
false,
);
});
History? history;
@ -69,27 +60,9 @@ class NovelReaderController extends _$NovelReaderController {
..date = DateTime.now().millisecondsSinceEpoch.toString();
}
isar.writeTxnSync(() {
isar.historys.putSync(history!);
history!.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.historys.putSync(history);
history.chapter.saveSync();
if (empty) {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.addHistory,
null,
history.toJson(),
false,
);
} else {
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateHistory,
history.id,
history.toJson(),
false,
);
}
});
}
@ -102,15 +75,8 @@ class NovelReaderController extends _$NovelReaderController {
ch.isRead = isRead;
ch.lastPageRead = (maxOffset != 0 ? newOffset / maxOffset : 0)
.toString();
ch.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(ch);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
});
}
}
@ -121,15 +87,8 @@ class NovelReaderController extends _$NovelReaderController {
final chap = chapter;
isar.writeTxnSync(() {
chap.isBookmarked = !isBookmarked;
chap.updatedAt = DateTime.now().millisecondsSinceEpoch;
isar.chapters.putSync(chap);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateChapter,
chapter.id,
chapter.toJson(),
false,
);
});
}

View file

@ -7,7 +7,7 @@ part of 'novel_reader_controller_provider.dart';
// **************************************************************************
String _$novelReaderControllerHash() =>
r'f05612ee0d25a5e5592f4e931b4078d992079f37';
r'47354aa64609d94a875d58569b5c95257b736b76';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -1,7 +1,9 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/modules/more/settings/appearance/providers/theme_mode_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/custom_sliver_grouped_list_view.dart';
import 'package:isar/isar.dart';
@ -309,6 +311,9 @@ class _UpdatesScreenState extends ConsumerState<UpdatesScreen>
isar.writeTxnSync(() {
for (var update in updates) {
isar.updates.deleteSync(update.id!);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.removeUpdate, update.id, "{}", false);
}
});
if (mounted) {

View file

@ -4,12 +4,10 @@ import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/category.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/modules/library/providers/library_state_provider.dart';
import 'package:mangayomi/modules/library/widgets/list_tile_manga_category.dart';
import 'package:mangayomi/modules/manga/detail/widgets/chapter_filter_list_tile_widget.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/providers/l10n_providers.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
import 'package:super_sliver_list/super_sliver_list.dart';
@ -135,8 +133,9 @@ void showCategorySelectionDialog({
if (isBulk) {
for (var manga in bulkMangas) {
manga.categories = categoryIds;
manga.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(manga);
_syncManga(manga, isFavorite, ref);
}
} else {
if (!isFavorite) {
@ -145,8 +144,9 @@ void showCategorySelectionDialog({
DateTime.now().millisecondsSinceEpoch;
}
singleManga.categories = categoryIds;
singleManga.updatedAt =
DateTime.now().millisecondsSinceEpoch;
isar.mangas.putSync(singleManga);
_syncManga(singleManga, isFavorite, ref);
}
if (isBulk) {
ref.read(mangasListStateProvider.notifier).clear();
@ -167,12 +167,3 @@ void showCategorySelectionDialog({
),
);
}
void _syncManga(Manga manga, bool isFavorite, WidgetRef ref) {
final sync = ref.read(synchingProvider(syncId: 1).notifier);
if (isFavorite) {
sync.addChangedPart(ActionType.updateItem, manga.id, manga.toJson(), false);
} else {
sync.addChangedPart(ActionType.addItem, manga.id, manga.toJson(), false);
}
}

View file

@ -5,12 +5,10 @@ import 'package:go_router/go_router.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/model/m_manga.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/manga/detail/manga_detail_main.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/modules/widgets/custom_extended_image_provider.dart';
import 'package:mangayomi/router/router.dart';
import 'package:mangayomi/utils/extensions/build_context_extensions.dart';
@ -320,10 +318,9 @@ Future<void> pushToMangaReaderDetail({
.isEmptySync();
if (empty) {
isar.writeTxnSync(() {
isar.mangas.putSync(manga);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.addItem, null, manga.toJson(), false);
isar.mangas.putSync(
manga..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
});
}
@ -390,15 +387,11 @@ Future<void> pushToMangaReaderDetail({
} else {
final getManga = isar.mangas.filter().idEqualTo(mangaId).findFirstSync()!;
isar.writeTxnSync(() {
isar.mangas.putSync(getManga..favorite = !getManga.favorite!);
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateItem,
getManga.id,
getManga.toJson(),
false,
);
isar.mangas.putSync(
getManga
..favorite = !getManga.favorite!
..updatedAt = DateTime.now().millisecondsSinceEpoch,
);
});
}
}

View file

@ -6,7 +6,7 @@ part of 'router.dart';
// RiverpodGenerator
// **************************************************************************
String _$routerHash() => r'52271f834e5242820afdb209d765c3cee8f3fe5b';
String _$routerHash() => r'fe1b18b9e03bd3df71cf66eabd78f0da3ac36247';
/// See also [router].
@ProviderFor(router)

View file

@ -3,12 +3,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:isar/isar.dart';
import 'package:mangayomi/eval/lib.dart';
import 'package:mangayomi/main.dart';
import 'package:mangayomi/models/changed.dart';
import 'package:mangayomi/models/manga.dart';
import 'package:mangayomi/models/settings.dart';
import 'package:mangayomi/models/source.dart';
import 'package:mangayomi/modules/more/settings/browse/providers/browse_state_provider.dart';
import 'package:mangayomi/modules/more/settings/sync/providers/sync_providers.dart';
import 'package:mangayomi/services/http/m_client.dart';
import 'package:package_info_plus/package_info_plus.dart';
@ -105,17 +103,10 @@ Future<void> _updateSource(
..additionalParams = source.additionalParams ?? ""
..isObsolete = false
..notes = source.notes
..repo = repo;
..repo = repo
..updatedAt = DateTime.now().millisecondsSinceEpoch;
await isar.writeTxn(() async => isar.sources.put(updatedSource));
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(
ActionType.updateExtension,
updatedSource.id,
updatedSource.toJson(),
false,
);
}
Future<void> _addNewSource(
@ -146,11 +137,9 @@ Future<void> _addNewSource(
..appMinVerReq = source.appMinVerReq
..isObsolete = false
..notes = source.notes
..repo = repo;
..repo = repo
..updatedAt = DateTime.now().millisecondsSinceEpoch;
await isar.writeTxn(() async => isar.sources.put(newSource));
ref
.read(synchingProvider(syncId: 1).notifier)
.addChangedPart(ActionType.addExtension, null, newSource.toJson(), false);
}
Future<void> checkIfSourceIsObsolete(
@ -185,22 +174,13 @@ Future<void> checkIfSourceIsObsolete(
if (source.isObsolete != isNowObsolete) {
source.isObsolete = isNowObsolete;
source.updatedAt = DateTime.now().millisecondsSinceEpoch;
toUpdate.add(source);
}
}
if (toUpdate.isEmpty) return;
await isar.writeTxn(() => isar.sources.putAll(toUpdate));
final notifier = ref.read(synchingProvider(syncId: 1).notifier);
for (var source in toUpdate) {
notifier.addChangedPart(
ActionType.updateExtension,
source.id,
source.toJson(),
false,
);
}
}
int compareVersions(String version1, String version2) {

View file

@ -49,10 +49,13 @@ class SyncServer extends _$SyncServer {
headers: {'Content-Type': 'application/json'},
body: jsonEncode({'email': username, 'password': password}),
);
var jsonData = jsonDecode(response.body) as Map<String, dynamic>;
if (response.statusCode != 200) {
return (false, jsonData["error"] as String);
var cookieHeader = response.headers["set-cookie"];
var startIdx = cookieHeader?.indexOf("id=") ?? -1;
var endIdx = cookieHeader?.indexOf(";", startIdx) ?? -1;
if (startIdx != -1 && endIdx != -1) {
return (false, "Auth failed");
}
final authToken = cookieHeader!.substring(startIdx + 3, endIdx);
ref
.read(synchingProvider(syncId: syncId).notifier)
.login(
@ -60,7 +63,7 @@ class SyncServer extends _$SyncServer {
syncId: syncId,
email: username,
server: server,
authToken: jsonData["token"],
authToken: authToken,
),
);
botToast(l10n.sync_logged);
@ -84,7 +87,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_syncUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
body: jsonEncode({'changedParts': changedParts}),
);
@ -123,7 +126,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_checkUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode != 200) {
@ -150,7 +153,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_snapshotUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode != 200) {
@ -181,7 +184,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_snapshotUrl/$snapshotId'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode != 200) {
@ -214,7 +217,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_snapshotUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode == 400) {
@ -239,7 +242,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_snapshotUrl/$snapshotId'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode != 200) {
@ -262,7 +265,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_uploadUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
body: jsonEncode({'backupData': datas}),
);
@ -297,7 +300,7 @@ class SyncServer extends _$SyncServer {
Uri.parse('${_getServer()}$_downloadUrl'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
'Cookie': 'id=$accessToken',
},
);
if (response.statusCode != 200) {

View file

@ -6,7 +6,7 @@ part of 'sync_server.dart';
// RiverpodGenerator
// **************************************************************************
String _$syncServerHash() => r'f973d04732090056e127d6d882146adfd192705d';
String _$syncServerHash() => r'46e14525f2bc99d08884e35f45dda5902e835bb5';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -6,7 +6,7 @@ part of 'anilist.dart';
// RiverpodGenerator
// **************************************************************************
String _$anilistHash() => r'530f1aaee260808ae894e4da0604b8b34e4f3742';
String _$anilistHash() => r'179af3d1b13b4a03d5009e5519195fee1f8ec0f7';
/// Copied from Dart SDK
class _SystemHash {

View file

@ -6,7 +6,7 @@ part of 'myanimelist.dart';
// RiverpodGenerator
// **************************************************************************
String _$myAnimeListHash() => r'885e6c50439c699f12c4f17c9e26b4a53b1d2036';
String _$myAnimeListHash() => r'98746d3f3ac88a6165b46de18acb268dc32a16f8';
/// Copied from Dart SDK
class _SystemHash {