mirror of
https://github.com/kodjodevf/mangayomi.git
synced 2026-03-11 17:25:32 +00:00
feat/pick-cover-image-from-trackers
-ability to choose anime/manga cover image from trackers as custom image
This commit is contained in:
parent
16e261ded3
commit
43be09db8f
15 changed files with 439 additions and 201 deletions
|
|
@ -42,6 +42,8 @@ class Manga {
|
|||
|
||||
List<byte>? customCoverImage;
|
||||
|
||||
String? customCoverFromTracker;
|
||||
|
||||
@Backlink(to: "manga")
|
||||
final chapters = IsarLinks<Chapter>();
|
||||
|
||||
|
|
@ -63,7 +65,8 @@ class Manga {
|
|||
this.categories,
|
||||
this.lastRead = 0,
|
||||
this.isLocalArchive = false,
|
||||
this.customCoverImage});
|
||||
this.customCoverImage,
|
||||
this.customCoverFromTracker});
|
||||
|
||||
Manga.fromJson(Map<String, dynamic> json) {
|
||||
author = json['author'];
|
||||
|
|
@ -84,6 +87,7 @@ class Manga {
|
|||
name = json['name'];
|
||||
source = json['source'];
|
||||
status = Status.values[json['status']];
|
||||
customCoverFromTracker = json['customCoverFromTracker'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
|
@ -104,7 +108,8 @@ class Manga {
|
|||
'link': link,
|
||||
'name': name,
|
||||
'source': source,
|
||||
'status': status.index
|
||||
'status': status.index,
|
||||
'customCoverFromTracker': customCoverFromTracker,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,78 +27,83 @@ const MangaSchema = CollectionSchema(
|
|||
name: r'categories',
|
||||
type: IsarType.longList,
|
||||
),
|
||||
r'customCoverImage': PropertySchema(
|
||||
r'customCoverFromTracker': PropertySchema(
|
||||
id: 2,
|
||||
name: r'customCoverFromTracker',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'customCoverImage': PropertySchema(
|
||||
id: 3,
|
||||
name: r'customCoverImage',
|
||||
type: IsarType.byteList,
|
||||
),
|
||||
r'dateAdded': PropertySchema(
|
||||
id: 3,
|
||||
id: 4,
|
||||
name: r'dateAdded',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'description': PropertySchema(
|
||||
id: 4,
|
||||
id: 5,
|
||||
name: r'description',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'favorite': PropertySchema(
|
||||
id: 5,
|
||||
id: 6,
|
||||
name: r'favorite',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'genre': PropertySchema(
|
||||
id: 6,
|
||||
id: 7,
|
||||
name: r'genre',
|
||||
type: IsarType.stringList,
|
||||
),
|
||||
r'imageUrl': PropertySchema(
|
||||
id: 7,
|
||||
id: 8,
|
||||
name: r'imageUrl',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'isLocalArchive': PropertySchema(
|
||||
id: 8,
|
||||
id: 9,
|
||||
name: r'isLocalArchive',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isManga': PropertySchema(
|
||||
id: 9,
|
||||
id: 10,
|
||||
name: r'isManga',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'lang': PropertySchema(
|
||||
id: 10,
|
||||
id: 11,
|
||||
name: r'lang',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'lastRead': PropertySchema(
|
||||
id: 11,
|
||||
id: 12,
|
||||
name: r'lastRead',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'lastUpdate': PropertySchema(
|
||||
id: 12,
|
||||
id: 13,
|
||||
name: r'lastUpdate',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'link': PropertySchema(
|
||||
id: 13,
|
||||
id: 14,
|
||||
name: r'link',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'name': PropertySchema(
|
||||
id: 14,
|
||||
id: 15,
|
||||
name: r'name',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'source': PropertySchema(
|
||||
id: 15,
|
||||
id: 16,
|
||||
name: r'source',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'status': PropertySchema(
|
||||
id: 16,
|
||||
id: 17,
|
||||
name: r'status',
|
||||
type: IsarType.byte,
|
||||
enumMap: _MangastatusEnumValueMap,
|
||||
|
|
@ -144,6 +149,12 @@ int _mangaEstimateSize(
|
|||
bytesCount += 3 + value.length * 8;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.customCoverFromTracker;
|
||||
if (value != null) {
|
||||
bytesCount += 3 + value.length * 3;
|
||||
}
|
||||
}
|
||||
{
|
||||
final value = object.customCoverImage;
|
||||
if (value != null) {
|
||||
|
|
@ -209,21 +220,22 @@ void _mangaSerialize(
|
|||
) {
|
||||
writer.writeString(offsets[0], object.author);
|
||||
writer.writeLongList(offsets[1], object.categories);
|
||||
writer.writeByteList(offsets[2], object.customCoverImage);
|
||||
writer.writeLong(offsets[3], object.dateAdded);
|
||||
writer.writeString(offsets[4], object.description);
|
||||
writer.writeBool(offsets[5], object.favorite);
|
||||
writer.writeStringList(offsets[6], object.genre);
|
||||
writer.writeString(offsets[7], object.imageUrl);
|
||||
writer.writeBool(offsets[8], object.isLocalArchive);
|
||||
writer.writeBool(offsets[9], object.isManga);
|
||||
writer.writeString(offsets[10], object.lang);
|
||||
writer.writeLong(offsets[11], object.lastRead);
|
||||
writer.writeLong(offsets[12], object.lastUpdate);
|
||||
writer.writeString(offsets[13], object.link);
|
||||
writer.writeString(offsets[14], object.name);
|
||||
writer.writeString(offsets[15], object.source);
|
||||
writer.writeByte(offsets[16], object.status.index);
|
||||
writer.writeString(offsets[2], object.customCoverFromTracker);
|
||||
writer.writeByteList(offsets[3], object.customCoverImage);
|
||||
writer.writeLong(offsets[4], object.dateAdded);
|
||||
writer.writeString(offsets[5], object.description);
|
||||
writer.writeBool(offsets[6], object.favorite);
|
||||
writer.writeStringList(offsets[7], object.genre);
|
||||
writer.writeString(offsets[8], object.imageUrl);
|
||||
writer.writeBool(offsets[9], object.isLocalArchive);
|
||||
writer.writeBool(offsets[10], object.isManga);
|
||||
writer.writeString(offsets[11], object.lang);
|
||||
writer.writeLong(offsets[12], object.lastRead);
|
||||
writer.writeLong(offsets[13], object.lastUpdate);
|
||||
writer.writeString(offsets[14], object.link);
|
||||
writer.writeString(offsets[15], object.name);
|
||||
writer.writeString(offsets[16], object.source);
|
||||
writer.writeByte(offsets[17], object.status.index);
|
||||
}
|
||||
|
||||
Manga _mangaDeserialize(
|
||||
|
|
@ -235,22 +247,23 @@ Manga _mangaDeserialize(
|
|||
final object = Manga(
|
||||
author: reader.readStringOrNull(offsets[0]),
|
||||
categories: reader.readLongList(offsets[1]),
|
||||
customCoverImage: reader.readByteList(offsets[2]),
|
||||
dateAdded: reader.readLongOrNull(offsets[3]),
|
||||
description: reader.readStringOrNull(offsets[4]),
|
||||
favorite: reader.readBoolOrNull(offsets[5]),
|
||||
genre: reader.readStringList(offsets[6]),
|
||||
customCoverFromTracker: reader.readStringOrNull(offsets[2]),
|
||||
customCoverImage: reader.readByteList(offsets[3]),
|
||||
dateAdded: reader.readLongOrNull(offsets[4]),
|
||||
description: reader.readStringOrNull(offsets[5]),
|
||||
favorite: reader.readBoolOrNull(offsets[6]),
|
||||
genre: reader.readStringList(offsets[7]),
|
||||
id: id,
|
||||
imageUrl: reader.readStringOrNull(offsets[7]),
|
||||
isLocalArchive: reader.readBoolOrNull(offsets[8]),
|
||||
isManga: reader.readBoolOrNull(offsets[9]),
|
||||
lang: reader.readStringOrNull(offsets[10]),
|
||||
lastRead: reader.readLongOrNull(offsets[11]),
|
||||
lastUpdate: reader.readLongOrNull(offsets[12]),
|
||||
link: reader.readStringOrNull(offsets[13]),
|
||||
name: reader.readStringOrNull(offsets[14]),
|
||||
source: reader.readStringOrNull(offsets[15]),
|
||||
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[16])] ??
|
||||
imageUrl: reader.readStringOrNull(offsets[8]),
|
||||
isLocalArchive: reader.readBoolOrNull(offsets[9]),
|
||||
isManga: reader.readBoolOrNull(offsets[10]),
|
||||
lang: reader.readStringOrNull(offsets[11]),
|
||||
lastRead: reader.readLongOrNull(offsets[12]),
|
||||
lastUpdate: reader.readLongOrNull(offsets[13]),
|
||||
link: reader.readStringOrNull(offsets[14]),
|
||||
name: reader.readStringOrNull(offsets[15]),
|
||||
source: reader.readStringOrNull(offsets[16]),
|
||||
status: _MangastatusValueEnumMap[reader.readByteOrNull(offsets[17])] ??
|
||||
Status.ongoing,
|
||||
);
|
||||
return object;
|
||||
|
|
@ -268,34 +281,36 @@ P _mangaDeserializeProp<P>(
|
|||
case 1:
|
||||
return (reader.readLongList(offset)) as P;
|
||||
case 2:
|
||||
return (reader.readByteList(offset)) as P;
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 3:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
return (reader.readByteList(offset)) as P;
|
||||
case 4:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 5:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 6:
|
||||
return (reader.readStringList(offset)) as P;
|
||||
case 7:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 8:
|
||||
case 6:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 7:
|
||||
return (reader.readStringList(offset)) as P;
|
||||
case 8:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 9:
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 10:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset)) as P;
|
||||
case 11:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 12:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 13:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 14:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 15:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 16:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 17:
|
||||
return (_MangastatusValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||
Status.ongoing) as P;
|
||||
default:
|
||||
|
|
@ -708,6 +723,162 @@ extension MangaQueryFilter on QueryBuilder<Manga, Manga, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
property: r'customCoverFromTracker',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerIsNotNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||
property: r'customCoverFromTracker',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerEqualTo(
|
||||
String? value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerGreaterThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
include: include,
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerLessThan(
|
||||
String? value, {
|
||||
bool include = false,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.lessThan(
|
||||
include: include,
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerBetween(
|
||||
String? lower,
|
||||
String? upper, {
|
||||
bool includeLower = true,
|
||||
bool includeUpper = true,
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.between(
|
||||
property: r'customCoverFromTracker',
|
||||
lower: lower,
|
||||
includeLower: includeLower,
|
||||
upper: upper,
|
||||
includeUpper: includeUpper,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerStartsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.startsWith(
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerEndsWith(
|
||||
String value, {
|
||||
bool caseSensitive = true,
|
||||
}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.endsWith(
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerContains(String value,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.contains(
|
||||
property: r'customCoverFromTracker',
|
||||
value: value,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerMatches(String pattern,
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.matches(
|
||||
property: r'customCoverFromTracker',
|
||||
wildcard: pattern,
|
||||
caseSensitive: caseSensitive,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerIsEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'customCoverFromTracker',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition>
|
||||
customCoverFromTrackerIsNotEmpty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||
property: r'customCoverFromTracker',
|
||||
value: '',
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterFilterCondition> customCoverImageIsNull() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(const FilterCondition.isNull(
|
||||
|
|
@ -2448,6 +2619,18 @@ extension MangaQuerySortBy on QueryBuilder<Manga, Manga, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> sortByCustomCoverFromTracker() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'customCoverFromTracker', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> sortByCustomCoverFromTrackerDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'customCoverFromTracker', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> sortByDateAdded() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'dateAdded', Sort.asc);
|
||||
|
|
@ -2618,6 +2801,18 @@ extension MangaQuerySortThenBy on QueryBuilder<Manga, Manga, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> thenByCustomCoverFromTracker() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'customCoverFromTracker', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> thenByCustomCoverFromTrackerDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'customCoverFromTracker', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QAfterSortBy> thenByDateAdded() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'dateAdded', Sort.asc);
|
||||
|
|
@ -2801,6 +2996,14 @@ extension MangaQueryWhereDistinct on QueryBuilder<Manga, Manga, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QDistinct> distinctByCustomCoverFromTracker(
|
||||
{bool caseSensitive = true}) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'customCoverFromTracker',
|
||||
caseSensitive: caseSensitive);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, Manga, QDistinct> distinctByCustomCoverImage() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'customCoverImage');
|
||||
|
|
@ -2917,6 +3120,13 @@ extension MangaQueryProperty on QueryBuilder<Manga, Manga, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, String?, QQueryOperations>
|
||||
customCoverFromTrackerProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'customCoverFromTracker');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Manga, List<int>?, QQueryOperations> customCoverImageProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'customCoverImage');
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ part of 'anime_player_controller_provider.dart';
|
|||
// **************************************************************************
|
||||
|
||||
String _$animeStreamControllerHash() =>
|
||||
r'05102c5a067600752d15236c270f5eb1ab553980';
|
||||
r'bf0730758333f74352257fb6afd2d0d0a319044f';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -235,7 +235,6 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final getMangaDetail = widget.manga;
|
||||
final l10n = l10nLocalizations(context)!;
|
||||
return GestureDetector(
|
||||
onTap: () async {
|
||||
pushToMangaReaderDetail(
|
||||
|
|
@ -254,6 +253,7 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
.sourceEqualTo(widget.source.name)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
final hasData = snapshot.hasData && snapshot.data!.isNotEmpty;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: Stack(
|
||||
|
|
@ -261,26 +261,30 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
SizedBox(
|
||||
width: 110,
|
||||
child: Column(children: [
|
||||
snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.customCoverImage != null
|
||||
? Image.memory(snapshot.data!.first.customCoverImage
|
||||
as Uint8List)
|
||||
: ClipRRect(
|
||||
Builder(
|
||||
builder: (context) {
|
||||
if (hasData &&
|
||||
snapshot.data!.first.customCoverImage != null) {
|
||||
return Image.memory(snapshot
|
||||
.data!.first.customCoverImage as Uint8List);
|
||||
}
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
child: cachedNetworkImage(
|
||||
headers: ref.watch(headersProvider(
|
||||
source: widget.source.name!,
|
||||
lang: widget.source.lang!)),
|
||||
imageUrl: snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.imageUrl != null
|
||||
? toImgUrl(snapshot.data!.first.imageUrl!)
|
||||
: toImgUrl(getMangaDetail.imageUrl!),
|
||||
imageUrl: toImgUrl(hasData
|
||||
? snapshot.data!.first
|
||||
.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
""
|
||||
: getMangaDetail.imageUrl!),
|
||||
width: 110,
|
||||
height: 150,
|
||||
fit: BoxFit.fill),
|
||||
),
|
||||
fit: BoxFit.fill));
|
||||
},
|
||||
),
|
||||
BottomTextWidget(
|
||||
fontSize: 12.0,
|
||||
text: widget.manga.name!,
|
||||
|
|
@ -293,33 +297,19 @@ class _MangaGlobalImageCardState extends ConsumerState<MangaGlobalImageCard>
|
|||
Container(
|
||||
width: 110,
|
||||
height: 150,
|
||||
color: snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.favorite!
|
||||
color: hasData && snapshot.data!.first.favorite!
|
||||
? Colors.black.withOpacity(0.7)
|
||||
: null,
|
||||
),
|
||||
if (snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.favorite!)
|
||||
if (hasData && snapshot.data!.first.favorite!)
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor(context),
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: Text(
|
||||
l10n.in_library,
|
||||
style: const TextStyle(fontSize: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
)),
|
||||
child: Icon(Icons.collections_bookmark,
|
||||
color: primaryColor(context)),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import 'package:mangayomi/modules/history/providers/isar_providers.dart';
|
|||
import 'package:mangayomi/modules/manga/reader/providers/push_router.dart';
|
||||
import 'package:mangayomi/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/utils/cached_network.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
import 'package:mangayomi/utils/date.dart';
|
||||
import 'package:mangayomi/utils/headers.dart';
|
||||
import 'package:mangayomi/modules/library/widgets/search_text_form_field.dart';
|
||||
|
|
@ -260,7 +261,9 @@ class _HistoryTabState extends ConsumerState<HistoryTab> {
|
|||
headers: ref.watch(headersProvider(
|
||||
source: manga.source!,
|
||||
lang: manga.lang!)),
|
||||
imageUrl: manga.imageUrl!,
|
||||
imageUrl: toImgUrl(
|
||||
manga.customCoverFromTracker ??
|
||||
manga.imageUrl!),
|
||||
width: 60,
|
||||
height: 90,
|
||||
fit: BoxFit.cover),
|
||||
|
|
|
|||
|
|
@ -2374,7 +2374,7 @@ final isLongPressedMangaStateProvider =
|
|||
|
||||
typedef _$IsLongPressedMangaState = AutoDisposeNotifier<bool>;
|
||||
String _$mangasSetIsReadStateHash() =>
|
||||
r'f283b6c15d908212b462a2dacbf776eeead863fe';
|
||||
r'8f86296f588a48747de625e0471048978ee9bdeb';
|
||||
|
||||
abstract class _$MangasSetIsReadState
|
||||
extends BuildlessAutoDisposeNotifier<void> {
|
||||
|
|
@ -2519,7 +2519,7 @@ class _MangasSetIsReadStateProviderElement
|
|||
}
|
||||
|
||||
String _$mangasSetUnReadStateHash() =>
|
||||
r'198aba4f8eb504fc05dbd003e8eb5c4d12d31ff7';
|
||||
r'3413e731b2fd8476a4032d3e47b943ca12f25090';
|
||||
|
||||
abstract class _$MangasSetUnReadState
|
||||
extends BuildlessAutoDisposeNotifier<void> {
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ class LibraryGridViewWidget extends StatelessWidget {
|
|||
? MemoryImage(entry.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
toImgUrl(entry.imageUrl!),
|
||||
toImgUrl(entry.customCoverFromTracker ?? entry.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: entry.source!, lang: entry.lang!)),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ class LibraryListViewWidget extends StatelessWidget {
|
|||
? MemoryImage(entry.customCoverImage
|
||||
as Uint8List) as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
toImgUrl(entry.imageUrl!),
|
||||
toImgUrl(
|
||||
entry.customCoverFromTracker ??
|
||||
entry.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: entry.source!,
|
||||
lang: entry.lang!)),
|
||||
|
|
|
|||
|
|
@ -234,7 +234,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
headers: ref.watch(headersProvider(
|
||||
source: widget.manga!.source!,
|
||||
lang: widget.manga!.lang!)),
|
||||
imageUrl: toImgUrl(widget.manga!.imageUrl!),
|
||||
imageUrl: toImgUrl(
|
||||
widget.manga!.customCoverFromTracker ??
|
||||
widget.manga!.imageUrl!),
|
||||
width: mediaWidth(context, 1),
|
||||
height: 300,
|
||||
fit: BoxFit.cover),
|
||||
|
|
@ -1320,7 +1322,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
final imageProvider = widget.manga!.customCoverImage != null
|
||||
? MemoryImage(widget.manga!.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(toImgUrl(widget.manga!.imageUrl!),
|
||||
: CachedNetworkImageProvider(
|
||||
toImgUrl(widget.manga!.customCoverFromTracker ??
|
||||
widget.manga!.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: widget.manga!.source!, lang: widget.manga!.lang!)));
|
||||
return Padding(
|
||||
|
|
@ -1506,23 +1510,91 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
right: 0,
|
||||
child: Row(
|
||||
children: [
|
||||
if (!isLocalArchive)
|
||||
if (widget.manga!.customCoverImage != null)
|
||||
Column(
|
||||
children: [
|
||||
StreamBuilder(
|
||||
stream: isar.trackPreferences
|
||||
.filter()
|
||||
.syncIdIsNotNull()
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
List<TrackPreference>? entries =
|
||||
snapshot.hasData ? snapshot.data! : [];
|
||||
if (entries.isEmpty) {
|
||||
return Container();
|
||||
}
|
||||
return Column(
|
||||
children: entries
|
||||
.map((e) => Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: MaterialButton(
|
||||
padding: const EdgeInsets.all(0),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10)),
|
||||
onPressed: () async {
|
||||
final trackSearch =
|
||||
await trackersSearchraggableMenu(
|
||||
context,
|
||||
isManga: widget.manga!.isManga!,
|
||||
track: Track(
|
||||
status:
|
||||
TrackStatus.planToRead,
|
||||
syncId: e.syncId!,
|
||||
title: widget.manga!.name!),
|
||||
) as TrackSearch?;
|
||||
if (trackSearch != null) {
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.putSync(widget
|
||||
.manga!
|
||||
..customCoverFromTracker =
|
||||
trackSearch.coverUrl);
|
||||
});
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(10),
|
||||
color:
|
||||
trackInfos(e.syncId!).$3),
|
||||
width: 45,
|
||||
height: 50,
|
||||
child: Image.asset(
|
||||
trackInfos(e.syncId!).$1,
|
||||
height: 30,
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
.toList(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
PopupMenuButton(
|
||||
itemBuilder: (context) {
|
||||
return [
|
||||
const PopupMenuItem<int>(
|
||||
value: 0, child: Text("Delete")),
|
||||
const PopupMenuItem<int>(
|
||||
value: 1, child: Text("Edit")),
|
||||
if (widget.manga!.customCoverImage != null ||
|
||||
widget.manga!.customCoverFromTracker !=
|
||||
null)
|
||||
PopupMenuItem<int>(
|
||||
value: 0,
|
||||
child: Text(context.l10n.delete)),
|
||||
PopupMenuItem<int>(
|
||||
value: 1, child: Text(context.l10n.edit)),
|
||||
];
|
||||
},
|
||||
onSelected: (value) async {
|
||||
final manga = widget.manga!;
|
||||
if (value == 0) {
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas
|
||||
.putSync(manga..customCoverImage = null);
|
||||
isar.mangas.putSync(manga
|
||||
..customCoverImage = null
|
||||
..customCoverFromTracker = null);
|
||||
});
|
||||
} else if (value == 1) {
|
||||
FilePickerResult? result =
|
||||
|
|
@ -1544,9 +1616,9 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: const Padding(
|
||||
|
|
@ -1555,51 +1627,22 @@ class _MangaDetailViewState extends ConsumerState<MangaDetailView>
|
|||
child: Icon(Icons.edit_outlined)),
|
||||
),
|
||||
),
|
||||
// IconButton(
|
||||
// onPressed: () async {
|
||||
// Uint8List? bytes;
|
||||
// if (isLocalArchive) {
|
||||
// bytes =
|
||||
// widget.manga!.customCoverImage as Uint8List?;
|
||||
// }
|
||||
// await Share.shareXFiles([
|
||||
// XFile.fromData(bytes!,
|
||||
// name: widget.manga!.name,
|
||||
// mimeType: 'image/jpeg')
|
||||
// ]);
|
||||
// },
|
||||
// icon: const CircleAvatar(child: Icon(Icons.share))),
|
||||
|
||||
if (isLocalArchive ||
|
||||
widget.manga!.customCoverImage == null)
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
FilePickerResult? result =
|
||||
await FilePicker.platform.pickFiles(
|
||||
type: FileType.custom,
|
||||
allowedExtensions: [
|
||||
'png',
|
||||
'jpg',
|
||||
'jpeg'
|
||||
]);
|
||||
if (result != null) {
|
||||
if (result.files.first.size < 5000000) {
|
||||
final manga = widget.manga!;
|
||||
final customCoverImage =
|
||||
File(result.files.first.path!)
|
||||
.readAsBytesSync();
|
||||
isar.writeTxnSync(() {
|
||||
isar.mangas.putSync(manga
|
||||
..customCoverImage = customCoverImage);
|
||||
});
|
||||
if (mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
icon: const CircleAvatar(
|
||||
child: Icon(Icons.edit_outlined))),
|
||||
// IconButton(
|
||||
// onPressed: () async {
|
||||
// Uint8List? bytes;
|
||||
// if (isLocalArchive) {
|
||||
// bytes =
|
||||
// widget.manga!.customCoverImage as Uint8List?;
|
||||
// }
|
||||
// await Share.shareXFiles([
|
||||
// XFile.fromData(bytes!,
|
||||
// name: widget.manga!.name,
|
||||
// mimeType: 'image/jpeg')
|
||||
// ]);
|
||||
// },
|
||||
// icon: const CircleAvatar(child: Icon(Icons.share))),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'update_manga_detail_providers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$updateMangaDetailHash() => r'7c528575751a4c88f3ea80edc87973dd668fba6c';
|
||||
String _$updateMangaDetailHash() => r'753f7db14ba8284ede82e9c8baec4344b28acedb';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -229,17 +229,22 @@ trackersSearchraggableMenu(BuildContext context,
|
|||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: const Icon(Icons.clear)),
|
||||
)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
icon: const Icon(Icons.clear)),
|
||||
)
|
||||
],
|
||||
),
|
||||
const Divider()
|
||||
],
|
||||
),
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ class _CurrentIndexProviderElement
|
|||
Chapter get chapter => (origin as CurrentIndexProvider).chapter;
|
||||
}
|
||||
|
||||
String _$readerControllerHash() => r'e6191b82e9cbbe2856c4c46b407ccd5da9206c8e';
|
||||
String _$readerControllerHash() => r'0b60b5d4cafa82d45d1e180969af0b7c982b1f82';
|
||||
|
||||
abstract class _$ReaderController extends BuildlessAutoDisposeNotifier<void> {
|
||||
late final Chapter chapter;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ 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/providers/l10n_providers.dart';
|
||||
import 'package:mangayomi/router/router.dart';
|
||||
import 'package:mangayomi/utils/colors.dart';
|
||||
import 'package:mangayomi/utils/constant.dart';
|
||||
|
|
@ -32,7 +31,6 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final l10n = l10nLocalizations(context);
|
||||
return StreamBuilder(
|
||||
stream: isar.mangas
|
||||
.filter()
|
||||
|
|
@ -41,19 +39,18 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
.sourceEqualTo(source.name)
|
||||
.watch(fireImmediately: true),
|
||||
builder: (context, snapshot) {
|
||||
final hasData = snapshot.hasData && snapshot.data!.isNotEmpty;
|
||||
return CoverViewWidget(
|
||||
image: snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.customCoverImage != null
|
||||
image: hasData && snapshot.data!.first.customCoverImage != null
|
||||
? MemoryImage(
|
||||
snapshot.data!.first.customCoverImage as Uint8List)
|
||||
as ImageProvider
|
||||
: CachedNetworkImageProvider(
|
||||
snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.imageUrl != null
|
||||
? toImgUrl(snapshot.data!.first.imageUrl!)
|
||||
: toImgUrl(getMangaDetail!.imageUrl!),
|
||||
toImgUrl(hasData
|
||||
? snapshot.data!.first.customCoverFromTracker ??
|
||||
snapshot.data!.first.imageUrl ??
|
||||
""
|
||||
: getMangaDetail!.imageUrl!),
|
||||
headers: ref.watch(headersProvider(
|
||||
source: source.name!, lang: source.lang!)),
|
||||
),
|
||||
|
|
@ -67,35 +64,18 @@ class MangaImageCardWidget extends ConsumerWidget {
|
|||
},
|
||||
children: [
|
||||
Container(
|
||||
color: snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.favorite!
|
||||
? Colors.black.withOpacity(0.7)
|
||||
color: hasData && snapshot.data!.first.favorite!
|
||||
? Colors.black.withOpacity(0.6)
|
||||
: null,
|
||||
),
|
||||
if (snapshot.hasData &&
|
||||
snapshot.data!.isNotEmpty &&
|
||||
snapshot.data!.first.favorite!)
|
||||
if (hasData && snapshot.data!.first.favorite!)
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor(context),
|
||||
borderRadius: BorderRadius.circular(5)),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(2),
|
||||
child: Text(
|
||||
l10n!.in_library,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: Theme.of(context)
|
||||
.scaffoldBackgroundColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Icon(Icons.collections_bookmark,
|
||||
color: primaryColor(context)),
|
||||
)),
|
||||
BottomTextWidget(text: getMangaDetail!.name!)
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'kitsu.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$kitsuHash() => r'c6a31bcfb827bba5d0938d350538a01926d42297';
|
||||
String _$kitsuHash() => r'425a6699eafe84e35320c9a66bce33b4ba332a52';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ part of 'headers.dart';
|
|||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$headersHash() => r'36e19ced66a55af45ef31bb3b342505246745ebe';
|
||||
String _$headersHash() => r'2075121328277856708a7f61718d22c409f915e0';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
|
|
|
|||
Loading…
Reference in a new issue