diff --git a/mobile/lib/domain/models/asset/remote_asset.model.dart b/mobile/lib/domain/models/asset/remote_asset.model.dart index 22648dac0f..36dc6242e1 100644 --- a/mobile/lib/domain/models/asset/remote_asset.model.dart +++ b/mobile/lib/domain/models/asset/remote_asset.model.dart @@ -81,10 +81,15 @@ class RemoteAsset extends BaseAsset { stackId == other.stackId; } - // Mirrors `==` above, which deliberately does not compare localId. @override int get hashCode => - super.hashCode ^ id.hashCode ^ ownerId.hashCode ^ thumbHash.hashCode ^ visibility.hashCode ^ stackId.hashCode; + super.hashCode ^ + id.hashCode ^ + ownerId.hashCode ^ + localId.hashCode ^ + thumbHash.hashCode ^ + visibility.hashCode ^ + stackId.hashCode; RemoteAsset copyWith({ String? id, diff --git a/mobile/lib/presentation/widgets/timeline/fixed/segment.model.dart b/mobile/lib/presentation/widgets/timeline/fixed/segment.model.dart index aa2112b8dd..32a2db58a2 100644 --- a/mobile/lib/presentation/widgets/timeline/fixed/segment.model.dart +++ b/mobile/lib/presentation/widgets/timeline/fixed/segment.model.dart @@ -234,7 +234,11 @@ class _AssetTileWidget extends ConsumerWidget { return false; } - return lockSelectionAssets.contains(asset); + // Iterate with `==` instead of `Set.contains` because `RemoteAsset.hashCode` + // includes `localId` while `==` does not — so the same server asset can + // hash to a different bucket when its `localId` differs (e.g., album-fetched + // copy has localId=null, merged-timeline copy has it populated). + return lockSelectionAssets.any((a) => a == asset); } @override