mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05:00 
			
		
		
		
	* add full image provider and refactor thumb providers * photo_view updates * wip: asset-viewer * fix controller dispose on page change * wip: bottom sheet * fix interactions * more bottomsheet changes * generate schema * PR feedback * refactor asset viewer * never rotate and fix background on page change * use photoview as the loading builder * precache after delay * claude: optimizing rebuild of image provider * claude: optimizing image decoding and caching * use proper cache for new full size image providers * chore: load local HEIC fullsize for iOS * make controller callbacks nullable * remove imageprovider cache * do not handle drag gestures when zoomed * use loadOriginal setting for HEIC / larger images * preload assets outside timer * never use same controllers in photo-view gallery * fix: cannot scroll down once swipe with bottom sheet --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Co-authored-by: Alex <alex.tran1502@gmail.com>
		
			
				
	
	
		
			173 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			173 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:drift/drift.dart' hide Query;
 | 
						|
import 'package:immich_mobile/domain/models/exif.model.dart' as domain;
 | 
						|
import 'package:immich_mobile/infrastructure/entities/exif.entity.drift.dart';
 | 
						|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
 | 
						|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
 | 
						|
import 'package:immich_mobile/infrastructure/utils/exif.converter.dart';
 | 
						|
import 'package:isar/isar.dart';
 | 
						|
 | 
						|
part 'exif.entity.g.dart';
 | 
						|
 | 
						|
/// Exif information 1:1 relation with Asset
 | 
						|
@Collection(inheritance: false)
 | 
						|
class ExifInfo {
 | 
						|
  final Id? id;
 | 
						|
  final int? fileSize;
 | 
						|
  final DateTime? dateTimeOriginal;
 | 
						|
  final String? timeZone;
 | 
						|
  final String? make;
 | 
						|
  final String? model;
 | 
						|
  final String? lens;
 | 
						|
  final float? f;
 | 
						|
  final float? mm;
 | 
						|
  final short? iso;
 | 
						|
  final float? exposureSeconds;
 | 
						|
  final float? lat;
 | 
						|
  final float? long;
 | 
						|
  final String? city;
 | 
						|
  final String? state;
 | 
						|
  final String? country;
 | 
						|
  final String? description;
 | 
						|
  final String? orientation;
 | 
						|
 | 
						|
  const ExifInfo({
 | 
						|
    this.id,
 | 
						|
    this.fileSize,
 | 
						|
    this.dateTimeOriginal,
 | 
						|
    this.timeZone,
 | 
						|
    this.make,
 | 
						|
    this.model,
 | 
						|
    this.lens,
 | 
						|
    this.f,
 | 
						|
    this.mm,
 | 
						|
    this.iso,
 | 
						|
    this.exposureSeconds,
 | 
						|
    this.lat,
 | 
						|
    this.long,
 | 
						|
    this.city,
 | 
						|
    this.state,
 | 
						|
    this.country,
 | 
						|
    this.description,
 | 
						|
    this.orientation,
 | 
						|
  });
 | 
						|
 | 
						|
  static ExifInfo fromDto(domain.ExifInfo dto) => ExifInfo(
 | 
						|
        id: dto.assetId,
 | 
						|
        fileSize: dto.fileSize,
 | 
						|
        dateTimeOriginal: dto.dateTimeOriginal,
 | 
						|
        timeZone: dto.timeZone,
 | 
						|
        make: dto.make,
 | 
						|
        model: dto.model,
 | 
						|
        lens: dto.lens,
 | 
						|
        f: dto.f,
 | 
						|
        mm: dto.mm,
 | 
						|
        iso: dto.iso?.toInt(),
 | 
						|
        exposureSeconds: dto.exposureSeconds,
 | 
						|
        lat: dto.latitude,
 | 
						|
        long: dto.longitude,
 | 
						|
        city: dto.city,
 | 
						|
        state: dto.state,
 | 
						|
        country: dto.country,
 | 
						|
        description: dto.description,
 | 
						|
        orientation: dto.orientation,
 | 
						|
      );
 | 
						|
 | 
						|
  domain.ExifInfo toDto() => domain.ExifInfo(
 | 
						|
        assetId: id,
 | 
						|
        fileSize: fileSize,
 | 
						|
        description: description,
 | 
						|
        orientation: orientation,
 | 
						|
        timeZone: timeZone,
 | 
						|
        dateTimeOriginal: dateTimeOriginal,
 | 
						|
        isFlipped: ExifDtoConverter.isOrientationFlipped(orientation),
 | 
						|
        latitude: lat,
 | 
						|
        longitude: long,
 | 
						|
        city: city,
 | 
						|
        state: state,
 | 
						|
        country: country,
 | 
						|
        make: make,
 | 
						|
        model: model,
 | 
						|
        lens: lens,
 | 
						|
        f: f,
 | 
						|
        mm: mm,
 | 
						|
        iso: iso?.toInt(),
 | 
						|
        exposureSeconds: exposureSeconds,
 | 
						|
      );
 | 
						|
}
 | 
						|
 | 
						|
class RemoteExifEntity extends Table with DriftDefaultsMixin {
 | 
						|
  const RemoteExifEntity();
 | 
						|
 | 
						|
  TextColumn get assetId =>
 | 
						|
      text().references(RemoteAssetEntity, #id, onDelete: KeyAction.cascade)();
 | 
						|
 | 
						|
  TextColumn get city => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get state => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get country => text().nullable()();
 | 
						|
 | 
						|
  DateTimeColumn get dateTimeOriginal => dateTime().nullable()();
 | 
						|
 | 
						|
  TextColumn get description => text().nullable()();
 | 
						|
 | 
						|
  IntColumn get height => integer().nullable()();
 | 
						|
 | 
						|
  IntColumn get width => integer().nullable()();
 | 
						|
 | 
						|
  TextColumn get exposureTime => text().nullable()();
 | 
						|
 | 
						|
  RealColumn get fNumber => real().nullable()();
 | 
						|
 | 
						|
  IntColumn get fileSize => integer().nullable()();
 | 
						|
 | 
						|
  RealColumn get focalLength => real().nullable()();
 | 
						|
 | 
						|
  RealColumn get latitude => real().nullable()();
 | 
						|
 | 
						|
  RealColumn get longitude => real().nullable()();
 | 
						|
 | 
						|
  IntColumn get iso => integer().nullable()();
 | 
						|
 | 
						|
  TextColumn get make => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get model => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get lens => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get orientation => text().nullable()();
 | 
						|
 | 
						|
  TextColumn get timeZone => text().nullable()();
 | 
						|
 | 
						|
  IntColumn get rating => integer().nullable()();
 | 
						|
 | 
						|
  TextColumn get projectionType => text().nullable()();
 | 
						|
 | 
						|
  @override
 | 
						|
  Set<Column> get primaryKey => {assetId};
 | 
						|
}
 | 
						|
 | 
						|
extension RemoteExifEntityDataDomainEx on RemoteExifEntityData {
 | 
						|
  domain.ExifInfo toDto() => domain.ExifInfo(
 | 
						|
        fileSize: fileSize,
 | 
						|
        dateTimeOriginal: dateTimeOriginal,
 | 
						|
        timeZone: timeZone,
 | 
						|
        make: make,
 | 
						|
        model: model,
 | 
						|
        iso: iso,
 | 
						|
        city: city,
 | 
						|
        state: state,
 | 
						|
        country: country,
 | 
						|
        description: description,
 | 
						|
        orientation: orientation,
 | 
						|
        latitude: latitude,
 | 
						|
        longitude: longitude,
 | 
						|
        f: fNumber?.toDouble(),
 | 
						|
        mm: focalLength?.toDouble(),
 | 
						|
        lens: lens,
 | 
						|
        width: width?.toDouble(),
 | 
						|
        height: height?.toDouble(),
 | 
						|
        isFlipped: ExifDtoConverter.isOrientationFlipped(orientation),
 | 
						|
      );
 | 
						|
}
 |