mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
fix(mobile): handle readonly and offline assets (#5565)
* feat: add isReadOnly and isOffline fields to Asset collection * refactor: move asset iterable filters to extension * hide asset actions based on offline and readOnly fields * pr changes * chore: doc comments --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
parent
56cde0438c
commit
a233e176e5
10 changed files with 333 additions and 105 deletions
|
|
@ -32,6 +32,8 @@ class Asset {
|
|||
isFavorite = remote.isFavorite,
|
||||
isArchived = remote.isArchived,
|
||||
isTrashed = remote.isTrashed,
|
||||
isReadOnly = remote.isReadOnly,
|
||||
isOffline = remote.isOffline,
|
||||
stackParentId = remote.stackParentId,
|
||||
stackCount = remote.stackCount;
|
||||
|
||||
|
|
@ -49,6 +51,8 @@ class Asset {
|
|||
isFavorite = local.isFavorite,
|
||||
isArchived = false,
|
||||
isTrashed = false,
|
||||
isReadOnly = false,
|
||||
isOffline = false,
|
||||
stackCount = 0,
|
||||
fileCreatedAt = local.createDateTime {
|
||||
if (fileCreatedAt.year == 1970) {
|
||||
|
|
@ -77,11 +81,13 @@ class Asset {
|
|||
required this.fileName,
|
||||
this.livePhotoVideoId,
|
||||
this.exifInfo,
|
||||
required this.isFavorite,
|
||||
required this.isArchived,
|
||||
required this.isTrashed,
|
||||
this.isFavorite = false,
|
||||
this.isArchived = false,
|
||||
this.isTrashed = false,
|
||||
this.stackParentId,
|
||||
required this.stackCount,
|
||||
this.stackCount = 0,
|
||||
this.isReadOnly = false,
|
||||
this.isOffline = false,
|
||||
});
|
||||
|
||||
@ignore
|
||||
|
|
@ -148,6 +154,10 @@ class Asset {
|
|||
|
||||
bool isTrashed;
|
||||
|
||||
bool isReadOnly;
|
||||
|
||||
bool isOffline;
|
||||
|
||||
@ignore
|
||||
ExifInfo? exifInfo;
|
||||
|
||||
|
|
@ -256,6 +266,8 @@ class Asset {
|
|||
isFavorite != a.isFavorite ||
|
||||
isArchived != a.isArchived ||
|
||||
isTrashed != a.isTrashed ||
|
||||
isReadOnly != a.isReadOnly ||
|
||||
isOffline != a.isOffline ||
|
||||
a.exifInfo?.latitude != exifInfo?.latitude ||
|
||||
a.exifInfo?.longitude != exifInfo?.longitude ||
|
||||
// no local stack count or different count from remote
|
||||
|
|
@ -288,6 +300,7 @@ class Asset {
|
|||
exifInfo: exifInfo ?? a.exifInfo?.copyWith(id: id),
|
||||
);
|
||||
} else {
|
||||
// TODO: Revisit this and remove all bool field assignments
|
||||
return a._copyWith(
|
||||
id: id,
|
||||
remoteId: remoteId,
|
||||
|
|
@ -297,6 +310,8 @@ class Asset {
|
|||
isFavorite: isFavorite,
|
||||
isArchived: isArchived,
|
||||
isTrashed: isTrashed,
|
||||
isReadOnly: isReadOnly,
|
||||
isOffline: isOffline,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -314,6 +329,8 @@ class Asset {
|
|||
isFavorite: a.isFavorite,
|
||||
isArchived: a.isArchived,
|
||||
isTrashed: a.isTrashed,
|
||||
isReadOnly: a.isReadOnly,
|
||||
isOffline: a.isOffline,
|
||||
exifInfo: a.exifInfo?.copyWith(id: id) ?? exifInfo,
|
||||
);
|
||||
} else {
|
||||
|
|
@ -346,6 +363,8 @@ class Asset {
|
|||
bool? isFavorite,
|
||||
bool? isArchived,
|
||||
bool? isTrashed,
|
||||
bool? isReadOnly,
|
||||
bool? isOffline,
|
||||
ExifInfo? exifInfo,
|
||||
String? stackParentId,
|
||||
int? stackCount,
|
||||
|
|
@ -368,6 +387,8 @@ class Asset {
|
|||
isFavorite: isFavorite ?? this.isFavorite,
|
||||
isArchived: isArchived ?? this.isArchived,
|
||||
isTrashed: isTrashed ?? this.isTrashed,
|
||||
isReadOnly: isReadOnly ?? this.isReadOnly,
|
||||
isOffline: isOffline ?? this.isOffline,
|
||||
exifInfo: exifInfo ?? this.exifInfo,
|
||||
stackParentId: stackParentId ?? this.stackParentId,
|
||||
stackCount: stackCount ?? this.stackCount,
|
||||
|
|
@ -426,7 +447,9 @@ class Asset {
|
|||
"width": ${width ?? "N/A"},
|
||||
"height": ${height ?? "N/A"},
|
||||
"isArchived": $isArchived,
|
||||
"isTrashed": $isTrashed
|
||||
"isTrashed": $isTrashed,
|
||||
"isReadOnly": $isReadOnly,
|
||||
"isOffline": $isOffline,
|
||||
}""";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
192
mobile/lib/shared/models/asset.g.dart
generated
192
mobile/lib/shared/models/asset.g.dart
generated
|
|
@ -57,54 +57,64 @@ const AssetSchema = CollectionSchema(
|
|||
name: r'isFavorite',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isTrashed': PropertySchema(
|
||||
r'isOffline': PropertySchema(
|
||||
id: 8,
|
||||
name: r'isOffline',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isReadOnly': PropertySchema(
|
||||
id: 9,
|
||||
name: r'isReadOnly',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'isTrashed': PropertySchema(
|
||||
id: 10,
|
||||
name: r'isTrashed',
|
||||
type: IsarType.bool,
|
||||
),
|
||||
r'livePhotoVideoId': PropertySchema(
|
||||
id: 9,
|
||||
id: 11,
|
||||
name: r'livePhotoVideoId',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'localId': PropertySchema(
|
||||
id: 10,
|
||||
id: 12,
|
||||
name: r'localId',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'ownerId': PropertySchema(
|
||||
id: 11,
|
||||
id: 13,
|
||||
name: r'ownerId',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'remoteId': PropertySchema(
|
||||
id: 12,
|
||||
id: 14,
|
||||
name: r'remoteId',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'stackCount': PropertySchema(
|
||||
id: 13,
|
||||
id: 15,
|
||||
name: r'stackCount',
|
||||
type: IsarType.long,
|
||||
),
|
||||
r'stackParentId': PropertySchema(
|
||||
id: 14,
|
||||
id: 16,
|
||||
name: r'stackParentId',
|
||||
type: IsarType.string,
|
||||
),
|
||||
r'type': PropertySchema(
|
||||
id: 15,
|
||||
id: 17,
|
||||
name: r'type',
|
||||
type: IsarType.byte,
|
||||
enumMap: _AssettypeEnumValueMap,
|
||||
),
|
||||
r'updatedAt': PropertySchema(
|
||||
id: 16,
|
||||
id: 18,
|
||||
name: r'updatedAt',
|
||||
type: IsarType.dateTime,
|
||||
),
|
||||
r'width': PropertySchema(
|
||||
id: 17,
|
||||
id: 19,
|
||||
name: r'width',
|
||||
type: IsarType.int,
|
||||
)
|
||||
|
|
@ -217,16 +227,18 @@ void _assetSerialize(
|
|||
writer.writeInt(offsets[5], object.height);
|
||||
writer.writeBool(offsets[6], object.isArchived);
|
||||
writer.writeBool(offsets[7], object.isFavorite);
|
||||
writer.writeBool(offsets[8], object.isTrashed);
|
||||
writer.writeString(offsets[9], object.livePhotoVideoId);
|
||||
writer.writeString(offsets[10], object.localId);
|
||||
writer.writeLong(offsets[11], object.ownerId);
|
||||
writer.writeString(offsets[12], object.remoteId);
|
||||
writer.writeLong(offsets[13], object.stackCount);
|
||||
writer.writeString(offsets[14], object.stackParentId);
|
||||
writer.writeByte(offsets[15], object.type.index);
|
||||
writer.writeDateTime(offsets[16], object.updatedAt);
|
||||
writer.writeInt(offsets[17], object.width);
|
||||
writer.writeBool(offsets[8], object.isOffline);
|
||||
writer.writeBool(offsets[9], object.isReadOnly);
|
||||
writer.writeBool(offsets[10], object.isTrashed);
|
||||
writer.writeString(offsets[11], object.livePhotoVideoId);
|
||||
writer.writeString(offsets[12], object.localId);
|
||||
writer.writeLong(offsets[13], object.ownerId);
|
||||
writer.writeString(offsets[14], object.remoteId);
|
||||
writer.writeLong(offsets[15], object.stackCount);
|
||||
writer.writeString(offsets[16], object.stackParentId);
|
||||
writer.writeByte(offsets[17], object.type.index);
|
||||
writer.writeDateTime(offsets[18], object.updatedAt);
|
||||
writer.writeInt(offsets[19], object.width);
|
||||
}
|
||||
|
||||
Asset _assetDeserialize(
|
||||
|
|
@ -243,19 +255,21 @@ Asset _assetDeserialize(
|
|||
fileName: reader.readString(offsets[4]),
|
||||
height: reader.readIntOrNull(offsets[5]),
|
||||
id: id,
|
||||
isArchived: reader.readBool(offsets[6]),
|
||||
isFavorite: reader.readBool(offsets[7]),
|
||||
isTrashed: reader.readBool(offsets[8]),
|
||||
livePhotoVideoId: reader.readStringOrNull(offsets[9]),
|
||||
localId: reader.readStringOrNull(offsets[10]),
|
||||
ownerId: reader.readLong(offsets[11]),
|
||||
remoteId: reader.readStringOrNull(offsets[12]),
|
||||
stackCount: reader.readLongOrNull(offsets[13]),
|
||||
stackParentId: reader.readStringOrNull(offsets[14]),
|
||||
type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[15])] ??
|
||||
isArchived: reader.readBoolOrNull(offsets[6]) ?? false,
|
||||
isFavorite: reader.readBoolOrNull(offsets[7]) ?? false,
|
||||
isOffline: reader.readBoolOrNull(offsets[8]) ?? false,
|
||||
isReadOnly: reader.readBoolOrNull(offsets[9]) ?? false,
|
||||
isTrashed: reader.readBoolOrNull(offsets[10]) ?? false,
|
||||
livePhotoVideoId: reader.readStringOrNull(offsets[11]),
|
||||
localId: reader.readStringOrNull(offsets[12]),
|
||||
ownerId: reader.readLong(offsets[13]),
|
||||
remoteId: reader.readStringOrNull(offsets[14]),
|
||||
stackCount: reader.readLongOrNull(offsets[15]),
|
||||
stackParentId: reader.readStringOrNull(offsets[16]),
|
||||
type: _AssettypeValueEnumMap[reader.readByteOrNull(offsets[17])] ??
|
||||
AssetType.other,
|
||||
updatedAt: reader.readDateTime(offsets[16]),
|
||||
width: reader.readIntOrNull(offsets[17]),
|
||||
updatedAt: reader.readDateTime(offsets[18]),
|
||||
width: reader.readIntOrNull(offsets[19]),
|
||||
);
|
||||
return object;
|
||||
}
|
||||
|
|
@ -280,29 +294,33 @@ P _assetDeserializeProp<P>(
|
|||
case 5:
|
||||
return (reader.readIntOrNull(offset)) as P;
|
||||
case 6:
|
||||
return (reader.readBool(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset) ?? false) as P;
|
||||
case 7:
|
||||
return (reader.readBool(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset) ?? false) as P;
|
||||
case 8:
|
||||
return (reader.readBool(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset) ?? false) as P;
|
||||
case 9:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset) ?? false) as P;
|
||||
case 10:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
return (reader.readBoolOrNull(offset) ?? false) as P;
|
||||
case 11:
|
||||
return (reader.readLong(offset)) as P;
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 12:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 13:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
return (reader.readLong(offset)) as P;
|
||||
case 14:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 15:
|
||||
return (reader.readLongOrNull(offset)) as P;
|
||||
case 16:
|
||||
return (reader.readStringOrNull(offset)) as P;
|
||||
case 17:
|
||||
return (_AssettypeValueEnumMap[reader.readByteOrNull(offset)] ??
|
||||
AssetType.other) as P;
|
||||
case 16:
|
||||
case 18:
|
||||
return (reader.readDateTime(offset)) as P;
|
||||
case 17:
|
||||
case 19:
|
||||
return (reader.readIntOrNull(offset)) as P;
|
||||
default:
|
||||
throw IsarError('Unknown property with id $propertyId');
|
||||
|
|
@ -1323,6 +1341,26 @@ extension AssetQueryFilter on QueryBuilder<Asset, Asset, QFilterCondition> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterFilterCondition> isOfflineEqualTo(
|
||||
bool value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'isOffline',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterFilterCondition> isReadOnlyEqualTo(
|
||||
bool value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addFilterCondition(FilterCondition.equalTo(
|
||||
property: r'isReadOnly',
|
||||
value: value,
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterFilterCondition> isTrashedEqualTo(
|
||||
bool value) {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
|
|
@ -2316,6 +2354,30 @@ extension AssetQuerySortBy on QueryBuilder<Asset, Asset, QSortBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> sortByIsOffline() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isOffline', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> sortByIsOfflineDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isOffline', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> sortByIsReadOnly() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isReadOnly', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> sortByIsReadOnlyDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isReadOnly', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> sortByIsTrashed() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isTrashed', Sort.asc);
|
||||
|
|
@ -2546,6 +2608,30 @@ extension AssetQuerySortThenBy on QueryBuilder<Asset, Asset, QSortThenBy> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> thenByIsOffline() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isOffline', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> thenByIsOfflineDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isOffline', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> thenByIsReadOnly() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isReadOnly', Sort.asc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> thenByIsReadOnlyDesc() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isReadOnly', Sort.desc);
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QAfterSortBy> thenByIsTrashed() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addSortBy(r'isTrashed', Sort.asc);
|
||||
|
|
@ -2718,6 +2804,18 @@ extension AssetQueryWhereDistinct on QueryBuilder<Asset, Asset, QDistinct> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QDistinct> distinctByIsOffline() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'isOffline');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QDistinct> distinctByIsReadOnly() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'isReadOnly');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, Asset, QDistinct> distinctByIsTrashed() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addDistinctBy(r'isTrashed');
|
||||
|
|
@ -2840,6 +2938,18 @@ extension AssetQueryProperty on QueryBuilder<Asset, Asset, QQueryProperty> {
|
|||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, bool, QQueryOperations> isOfflineProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'isOffline');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, bool, QQueryOperations> isReadOnlyProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'isReadOnly');
|
||||
});
|
||||
}
|
||||
|
||||
QueryBuilder<Asset, bool, QQueryOperations> isTrashedProperty() {
|
||||
return QueryBuilder.apply(this, (query) {
|
||||
return query.addPropertyName(r'isTrashed');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue