immich/mobile/lib/infrastructure/repositories/map.repository.dart

102 lines
3.2 KiB
Dart
Raw Normal View History

2025-07-16 15:18:27 +08:00
import 'package:drift/drift.dart';
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
import 'package:immich_mobile/domain/models/map.model.dart';
2025-07-16 17:28:01 +08:00
import 'package:immich_mobile/domain/services/map.service.dart';
2025-07-16 15:18:27 +08:00
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
2025-07-16 17:28:01 +08:00
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.drift.dart';
2025-07-16 15:18:27 +08:00
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
import 'package:maplibre_gl/maplibre_gl.dart';
import 'package:stream_transform/stream_transform.dart';
class DriftMapRepository extends DriftDatabaseRepository {
final Drift _db;
const DriftMapRepository(super._db) : _db = _db;
2025-07-16 17:28:01 +08:00
MapQuery remote(String ownerId) => _mapQueryBuilder(
assetFilter: (row) =>
row.deletedAt.isNull() &
row.visibility.equalsValue(AssetVisibility.timeline) &
row.ownerId.equals(ownerId),
2025-07-16 15:18:27 +08:00
);
2025-07-16 17:28:01 +08:00
MapQuery _mapQueryBuilder({
Expression<bool> Function($RemoteAssetEntityTable row)? assetFilter,
Expression<bool> Function($RemoteExifEntityTable row)? exifFilter,
}) {
return (
markerSource: (bounds) => _watchMapMarker(
assetFilter: assetFilter,
exifFilter: exifFilter,
bounds: bounds,
)
);
2025-07-16 15:18:27 +08:00
}
2025-07-16 17:28:01 +08:00
Stream<List<Marker>> _watchMapMarker({
Expression<bool> Function($RemoteAssetEntityTable row)? assetFilter,
Expression<bool> Function($RemoteExifEntityTable row)? exifFilter,
LatLngBounds? bounds,
2025-07-16 15:18:27 +08:00
}) {
final query = _db.remoteExifEntity.select().join([
innerJoin(
_db.remoteAssetEntity,
_db.remoteAssetEntity.id.equalsExp(_db.remoteExifEntity.assetId),
useColumns: false,
),
])
..where(
_db.remoteExifEntity.latitude.isNotNull() &
2025-07-16 17:28:01 +08:00
_db.remoteExifEntity.longitude.isNotNull(),
2025-07-16 15:18:27 +08:00
);
2025-07-16 17:28:01 +08:00
if (assetFilter != null) {
query.where(assetFilter(_db.remoteAssetEntity));
}
if (exifFilter != null) {
query.where(exifFilter(_db.remoteExifEntity));
}
if (bounds != null) {
query.where(_db.remoteExifEntity.inBounds(bounds));
}
2025-07-16 15:18:27 +08:00
return query
.map((row) => row.readTable(_db.remoteExifEntity).toMarker())
.watch()
.throttle(const Duration(seconds: 3));
}
}
extension MapBounds on $RemoteExifEntityTable {
Expression<bool> inBounds(LatLngBounds bounds) {
final isLatitudeInBounds =
latitude.isBiggerOrEqualValue(bounds.southwest.latitude) &
latitude.isSmallerOrEqualValue(bounds.northeast.latitude);
final Expression<bool> isLongitudeInBounds;
if (bounds.southwest.longitude <= bounds.northeast.longitude) {
isLongitudeInBounds =
longitude.isBiggerOrEqualValue(bounds.southwest.longitude) &
longitude.isSmallerOrEqualValue(bounds.northeast.longitude);
} else {
isLongitudeInBounds =
longitude.isBiggerOrEqualValue(bounds.southwest.longitude) |
longitude.isSmallerOrEqualValue(bounds.northeast.longitude);
}
return isLatitudeInBounds & isLongitudeInBounds;
}
}
extension on RemoteExifEntityData {
Marker toMarker() {
return Marker(
assetId: assetId,
location: LatLng(latitude!, longitude!),
);
}
}