mirror of
https://github.com/immich-app/immich.git
synced 2025-06-03 13:44:16 -04:00
feat(mobile): offer the same album sorting options on mobile as on web (#3804)
* Add translations for new album sort options * Support additional album sort options like on web * Update generated code * Fix lint --------- Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
f3b17d8f73
commit
e57c926676
@ -173,6 +173,8 @@
|
|||||||
"library_page_sharing": "Sharing",
|
"library_page_sharing": "Sharing",
|
||||||
"library_page_sort_created": "Most recently created",
|
"library_page_sort_created": "Most recently created",
|
||||||
"library_page_sort_title": "Album title",
|
"library_page_sort_title": "Album title",
|
||||||
|
"library_page_sort_most_recent_photo": "Most recent photo",
|
||||||
|
"library_page_sort_last_modified": "Last modified",
|
||||||
"login_disabled": "Login has been disabled",
|
"login_disabled": "Login has been disabled",
|
||||||
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
"login_form_api_exception": "API exception. Please check the server URL and try again.",
|
||||||
"login_form_handshake_exception": "There was an Handshake Exception with the server. Enable self-signed certificate support in the settings if you are using a self-signed certificate.",
|
"login_form_handshake_exception": "There was an Handshake Exception with the server. Enable self-signed certificate support in the settings if you are using a self-signed certificate.",
|
||||||
|
@ -47,6 +47,7 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
useState(settings.getSetting(AppSettingsEnum.selectedAlbumSortOrder));
|
useState(settings.getSetting(AppSettingsEnum.selectedAlbumSortOrder));
|
||||||
|
|
||||||
List<Album> sortedAlbums() {
|
List<Album> sortedAlbums() {
|
||||||
|
// Created.
|
||||||
if (selectedAlbumSortOrder.value == 0) {
|
if (selectedAlbumSortOrder.value == 0) {
|
||||||
return albums
|
return albums
|
||||||
.where((a) => a.isRemote)
|
.where((a) => a.isRemote)
|
||||||
@ -54,6 +55,34 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
.reversed
|
.reversed
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
// Album title.
|
||||||
|
if (selectedAlbumSortOrder.value == 1) {
|
||||||
|
return albums.where((a) => a.isRemote).sortedBy((album) => album.name);
|
||||||
|
}
|
||||||
|
// Most recent photo, if unset (e.g. empty album, use modifiedAt / updatedAt).
|
||||||
|
if (selectedAlbumSortOrder.value == 2) {
|
||||||
|
return albums
|
||||||
|
.where((a) => a.isRemote)
|
||||||
|
.sorted(
|
||||||
|
(a, b) => a.lastModifiedAssetTimestamp != null &&
|
||||||
|
b.lastModifiedAssetTimestamp != null
|
||||||
|
? a.lastModifiedAssetTimestamp!
|
||||||
|
.compareTo(b.lastModifiedAssetTimestamp!)
|
||||||
|
: a.modifiedAt.compareTo(b.modifiedAt),
|
||||||
|
)
|
||||||
|
.reversed
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
// Last modified.
|
||||||
|
if (selectedAlbumSortOrder.value == 3) {
|
||||||
|
return albums
|
||||||
|
.where((a) => a.isRemote)
|
||||||
|
.sortedBy((album) => album.modifiedAt)
|
||||||
|
.reversed
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: Album title.
|
||||||
return albums.where((a) => a.isRemote).sortedBy((album) => album.name);
|
return albums.where((a) => a.isRemote).sortedBy((album) => album.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +90,8 @@ class LibraryPage extends HookConsumerWidget {
|
|||||||
final options = [
|
final options = [
|
||||||
"library_page_sort_created".tr(),
|
"library_page_sort_created".tr(),
|
||||||
"library_page_sort_title".tr(),
|
"library_page_sort_title".tr(),
|
||||||
|
"library_page_sort_most_recent_photo".tr(),
|
||||||
|
"library_page_sort_last_modified".tr(),
|
||||||
];
|
];
|
||||||
|
|
||||||
return PopupMenuButton(
|
return PopupMenuButton(
|
||||||
|
@ -18,6 +18,7 @@ class Album {
|
|||||||
required this.name,
|
required this.name,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.modifiedAt,
|
required this.modifiedAt,
|
||||||
|
this.lastModifiedAssetTimestamp,
|
||||||
required this.shared,
|
required this.shared,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ class Album {
|
|||||||
String name;
|
String name;
|
||||||
DateTime createdAt;
|
DateTime createdAt;
|
||||||
DateTime modifiedAt;
|
DateTime modifiedAt;
|
||||||
|
DateTime? lastModifiedAssetTimestamp;
|
||||||
bool shared;
|
bool shared;
|
||||||
final IsarLink<User> owner = IsarLink<User>();
|
final IsarLink<User> owner = IsarLink<User>();
|
||||||
final IsarLink<Asset> thumbnail = IsarLink<Asset>();
|
final IsarLink<Asset> thumbnail = IsarLink<Asset>();
|
||||||
@ -83,12 +85,21 @@ class Album {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(other) {
|
bool operator ==(other) {
|
||||||
if (other is! Album) return false;
|
if (other is! Album) return false;
|
||||||
|
|
||||||
|
final lastModifiedAssetTimestampIsSetAndEqual =
|
||||||
|
lastModifiedAssetTimestamp != null &&
|
||||||
|
other.lastModifiedAssetTimestamp != null
|
||||||
|
? lastModifiedAssetTimestamp!
|
||||||
|
.isAtSameMomentAs(other.lastModifiedAssetTimestamp!)
|
||||||
|
: true;
|
||||||
|
|
||||||
return id == other.id &&
|
return id == other.id &&
|
||||||
remoteId == other.remoteId &&
|
remoteId == other.remoteId &&
|
||||||
localId == other.localId &&
|
localId == other.localId &&
|
||||||
name == other.name &&
|
name == other.name &&
|
||||||
createdAt.isAtSameMomentAs(other.createdAt) &&
|
createdAt.isAtSameMomentAs(other.createdAt) &&
|
||||||
modifiedAt.isAtSameMomentAs(other.modifiedAt) &&
|
modifiedAt.isAtSameMomentAs(other.modifiedAt) &&
|
||||||
|
lastModifiedAssetTimestampIsSetAndEqual &&
|
||||||
shared == other.shared &&
|
shared == other.shared &&
|
||||||
owner.value == other.owner.value &&
|
owner.value == other.owner.value &&
|
||||||
thumbnail.value == other.thumbnail.value &&
|
thumbnail.value == other.thumbnail.value &&
|
||||||
@ -105,6 +116,7 @@ class Album {
|
|||||||
name.hashCode ^
|
name.hashCode ^
|
||||||
createdAt.hashCode ^
|
createdAt.hashCode ^
|
||||||
modifiedAt.hashCode ^
|
modifiedAt.hashCode ^
|
||||||
|
lastModifiedAssetTimestamp.hashCode ^
|
||||||
shared.hashCode ^
|
shared.hashCode ^
|
||||||
owner.value.hashCode ^
|
owner.value.hashCode ^
|
||||||
thumbnail.value.hashCode ^
|
thumbnail.value.hashCode ^
|
||||||
@ -130,6 +142,7 @@ class Album {
|
|||||||
name: dto.albumName,
|
name: dto.albumName,
|
||||||
createdAt: dto.createdAt,
|
createdAt: dto.createdAt,
|
||||||
modifiedAt: dto.updatedAt,
|
modifiedAt: dto.updatedAt,
|
||||||
|
lastModifiedAssetTimestamp: dto.lastModifiedAssetTimestamp,
|
||||||
shared: dto.shared,
|
shared: dto.shared,
|
||||||
);
|
);
|
||||||
a.owner.value = await db.users.getById(dto.ownerId);
|
a.owner.value = await db.users.getById(dto.ownerId);
|
||||||
|
@ -22,28 +22,33 @@ const AlbumSchema = CollectionSchema(
|
|||||||
name: r'createdAt',
|
name: r'createdAt',
|
||||||
type: IsarType.dateTime,
|
type: IsarType.dateTime,
|
||||||
),
|
),
|
||||||
r'localId': PropertySchema(
|
r'lastModifiedAssetTimestamp': PropertySchema(
|
||||||
id: 1,
|
id: 1,
|
||||||
|
name: r'lastModifiedAssetTimestamp',
|
||||||
|
type: IsarType.dateTime,
|
||||||
|
),
|
||||||
|
r'localId': PropertySchema(
|
||||||
|
id: 2,
|
||||||
name: r'localId',
|
name: r'localId',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'modifiedAt': PropertySchema(
|
r'modifiedAt': PropertySchema(
|
||||||
id: 2,
|
id: 3,
|
||||||
name: r'modifiedAt',
|
name: r'modifiedAt',
|
||||||
type: IsarType.dateTime,
|
type: IsarType.dateTime,
|
||||||
),
|
),
|
||||||
r'name': PropertySchema(
|
r'name': PropertySchema(
|
||||||
id: 3,
|
id: 4,
|
||||||
name: r'name',
|
name: r'name',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'remoteId': PropertySchema(
|
r'remoteId': PropertySchema(
|
||||||
id: 4,
|
id: 5,
|
||||||
name: r'remoteId',
|
name: r'remoteId',
|
||||||
type: IsarType.string,
|
type: IsarType.string,
|
||||||
),
|
),
|
||||||
r'shared': PropertySchema(
|
r'shared': PropertySchema(
|
||||||
id: 5,
|
id: 6,
|
||||||
name: r'shared',
|
name: r'shared',
|
||||||
type: IsarType.bool,
|
type: IsarType.bool,
|
||||||
)
|
)
|
||||||
@ -143,11 +148,12 @@ void _albumSerialize(
|
|||||||
Map<Type, List<int>> allOffsets,
|
Map<Type, List<int>> allOffsets,
|
||||||
) {
|
) {
|
||||||
writer.writeDateTime(offsets[0], object.createdAt);
|
writer.writeDateTime(offsets[0], object.createdAt);
|
||||||
writer.writeString(offsets[1], object.localId);
|
writer.writeDateTime(offsets[1], object.lastModifiedAssetTimestamp);
|
||||||
writer.writeDateTime(offsets[2], object.modifiedAt);
|
writer.writeString(offsets[2], object.localId);
|
||||||
writer.writeString(offsets[3], object.name);
|
writer.writeDateTime(offsets[3], object.modifiedAt);
|
||||||
writer.writeString(offsets[4], object.remoteId);
|
writer.writeString(offsets[4], object.name);
|
||||||
writer.writeBool(offsets[5], object.shared);
|
writer.writeString(offsets[5], object.remoteId);
|
||||||
|
writer.writeBool(offsets[6], object.shared);
|
||||||
}
|
}
|
||||||
|
|
||||||
Album _albumDeserialize(
|
Album _albumDeserialize(
|
||||||
@ -158,11 +164,12 @@ Album _albumDeserialize(
|
|||||||
) {
|
) {
|
||||||
final object = Album(
|
final object = Album(
|
||||||
createdAt: reader.readDateTime(offsets[0]),
|
createdAt: reader.readDateTime(offsets[0]),
|
||||||
localId: reader.readStringOrNull(offsets[1]),
|
lastModifiedAssetTimestamp: reader.readDateTimeOrNull(offsets[1]),
|
||||||
modifiedAt: reader.readDateTime(offsets[2]),
|
localId: reader.readStringOrNull(offsets[2]),
|
||||||
name: reader.readString(offsets[3]),
|
modifiedAt: reader.readDateTime(offsets[3]),
|
||||||
remoteId: reader.readStringOrNull(offsets[4]),
|
name: reader.readString(offsets[4]),
|
||||||
shared: reader.readBool(offsets[5]),
|
remoteId: reader.readStringOrNull(offsets[5]),
|
||||||
|
shared: reader.readBool(offsets[6]),
|
||||||
);
|
);
|
||||||
object.id = id;
|
object.id = id;
|
||||||
return object;
|
return object;
|
||||||
@ -178,14 +185,16 @@ P _albumDeserializeProp<P>(
|
|||||||
case 0:
|
case 0:
|
||||||
return (reader.readDateTime(offset)) as P;
|
return (reader.readDateTime(offset)) as P;
|
||||||
case 1:
|
case 1:
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readDateTimeOrNull(offset)) as P;
|
||||||
case 2:
|
case 2:
|
||||||
return (reader.readDateTime(offset)) as P;
|
|
||||||
case 3:
|
|
||||||
return (reader.readString(offset)) as P;
|
|
||||||
case 4:
|
|
||||||
return (reader.readStringOrNull(offset)) as P;
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
case 3:
|
||||||
|
return (reader.readDateTime(offset)) as P;
|
||||||
|
case 4:
|
||||||
|
return (reader.readString(offset)) as P;
|
||||||
case 5:
|
case 5:
|
||||||
|
return (reader.readStringOrNull(offset)) as P;
|
||||||
|
case 6:
|
||||||
return (reader.readBool(offset)) as P;
|
return (reader.readBool(offset)) as P;
|
||||||
default:
|
default:
|
||||||
throw IsarError('Unknown property with id $propertyId');
|
throw IsarError('Unknown property with id $propertyId');
|
||||||
@ -520,6 +529,80 @@ extension AlbumQueryFilter on QueryBuilder<Album, Album, QFilterCondition> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampIsNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampIsNotNull() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(const FilterCondition.isNotNull(
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampEqualTo(DateTime? value) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.equalTo(
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampGreaterThan(
|
||||||
|
DateTime? value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.greaterThan(
|
||||||
|
include: include,
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampLessThan(
|
||||||
|
DateTime? value, {
|
||||||
|
bool include = false,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.lessThan(
|
||||||
|
include: include,
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
value: value,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterFilterCondition>
|
||||||
|
lastModifiedAssetTimestampBetween(
|
||||||
|
DateTime? lower,
|
||||||
|
DateTime? upper, {
|
||||||
|
bool includeLower = true,
|
||||||
|
bool includeUpper = true,
|
||||||
|
}) {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addFilterCondition(FilterCondition.between(
|
||||||
|
property: r'lastModifiedAssetTimestamp',
|
||||||
|
lower: lower,
|
||||||
|
includeLower: includeLower,
|
||||||
|
upper: upper,
|
||||||
|
includeUpper: includeUpper,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Album, Album, QAfterFilterCondition> localIdIsNull() {
|
QueryBuilder<Album, Album, QAfterFilterCondition> localIdIsNull() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addFilterCondition(const FilterCondition.isNull(
|
return query.addFilterCondition(const FilterCondition.isNull(
|
||||||
@ -1158,6 +1241,19 @@ extension AlbumQuerySortBy on QueryBuilder<Album, Album, QSortBy> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterSortBy> sortByLastModifiedAssetTimestamp() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastModifiedAssetTimestamp', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterSortBy>
|
||||||
|
sortByLastModifiedAssetTimestampDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastModifiedAssetTimestamp', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Album, Album, QAfterSortBy> sortByLocalId() {
|
QueryBuilder<Album, Album, QAfterSortBy> sortByLocalId() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'localId', Sort.asc);
|
return query.addSortBy(r'localId', Sort.asc);
|
||||||
@ -1244,6 +1340,19 @@ extension AlbumQuerySortThenBy on QueryBuilder<Album, Album, QSortThenBy> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterSortBy> thenByLastModifiedAssetTimestamp() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastModifiedAssetTimestamp', Sort.asc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QAfterSortBy>
|
||||||
|
thenByLastModifiedAssetTimestampDesc() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addSortBy(r'lastModifiedAssetTimestamp', Sort.desc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Album, Album, QAfterSortBy> thenByLocalId() {
|
QueryBuilder<Album, Album, QAfterSortBy> thenByLocalId() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addSortBy(r'localId', Sort.asc);
|
return query.addSortBy(r'localId', Sort.asc);
|
||||||
@ -1312,6 +1421,12 @@ extension AlbumQueryWhereDistinct on QueryBuilder<Album, Album, QDistinct> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, Album, QDistinct> distinctByLastModifiedAssetTimestamp() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addDistinctBy(r'lastModifiedAssetTimestamp');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Album, Album, QDistinct> distinctByLocalId(
|
QueryBuilder<Album, Album, QDistinct> distinctByLocalId(
|
||||||
{bool caseSensitive = true}) {
|
{bool caseSensitive = true}) {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
@ -1359,6 +1474,13 @@ extension AlbumQueryProperty on QueryBuilder<Album, Album, QQueryProperty> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QueryBuilder<Album, DateTime?, QQueryOperations>
|
||||||
|
lastModifiedAssetTimestampProperty() {
|
||||||
|
return QueryBuilder.apply(this, (query) {
|
||||||
|
return query.addPropertyName(r'lastModifiedAssetTimestamp');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
QueryBuilder<Album, String?, QQueryOperations> localIdProperty() {
|
QueryBuilder<Album, String?, QQueryOperations> localIdProperty() {
|
||||||
return QueryBuilder.apply(this, (query) {
|
return QueryBuilder.apply(this, (query) {
|
||||||
return query.addPropertyName(r'localId');
|
return query.addPropertyName(r'localId');
|
||||||
|
@ -282,6 +282,9 @@ class SyncService {
|
|||||||
if (!_hasAlbumResponseDtoChanged(dto, album)) {
|
if (!_hasAlbumResponseDtoChanged(dto, album)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// loadDetails (/api/album/:id) will not include lastModifiedAssetTimestamp,
|
||||||
|
// i.e. it will always be null. Save it here.
|
||||||
|
final originalDto = dto;
|
||||||
dto = await loadDetails(dto);
|
dto = await loadDetails(dto);
|
||||||
if (dto.assetCount != dto.assets.length) {
|
if (dto.assetCount != dto.assets.length) {
|
||||||
return false;
|
return false;
|
||||||
@ -321,6 +324,7 @@ class SyncService {
|
|||||||
album.name = dto.albumName;
|
album.name = dto.albumName;
|
||||||
album.shared = dto.shared;
|
album.shared = dto.shared;
|
||||||
album.modifiedAt = dto.updatedAt;
|
album.modifiedAt = dto.updatedAt;
|
||||||
|
album.lastModifiedAssetTimestamp = originalDto.lastModifiedAssetTimestamp;
|
||||||
if (album.thumbnail.value?.remoteId != dto.albumThumbnailAssetId) {
|
if (album.thumbnail.value?.remoteId != dto.albumThumbnailAssetId) {
|
||||||
album.thumbnail.value = await _db.assets
|
album.thumbnail.value = await _db.assets
|
||||||
.where()
|
.where()
|
||||||
@ -808,5 +812,13 @@ bool _hasAlbumResponseDtoChanged(AlbumResponseDto dto, Album a) {
|
|||||||
dto.albumThumbnailAssetId != a.thumbnail.value?.remoteId ||
|
dto.albumThumbnailAssetId != a.thumbnail.value?.remoteId ||
|
||||||
dto.shared != a.shared ||
|
dto.shared != a.shared ||
|
||||||
dto.sharedUsers.length != a.sharedUsers.length ||
|
dto.sharedUsers.length != a.sharedUsers.length ||
|
||||||
!dto.updatedAt.isAtSameMomentAs(a.modifiedAt);
|
!dto.updatedAt.isAtSameMomentAs(a.modifiedAt) ||
|
||||||
|
(dto.lastModifiedAssetTimestamp == null &&
|
||||||
|
a.lastModifiedAssetTimestamp != null) ||
|
||||||
|
(dto.lastModifiedAssetTimestamp != null &&
|
||||||
|
a.lastModifiedAssetTimestamp == null) ||
|
||||||
|
(dto.lastModifiedAssetTimestamp != null &&
|
||||||
|
a.lastModifiedAssetTimestamp != null &&
|
||||||
|
!dto.lastModifiedAssetTimestamp!
|
||||||
|
.isAtSameMomentAs(a.lastModifiedAssetTimestamp!));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user