import 'package:isar/isar.dart'; import 'package:openapi/api.dart'; part 'exif_info.g.dart'; /// Exif information 1:1 relation with Asset @Collection(inheritance: false) class ExifInfo { Id? id; int? fileSize; DateTime? dateTimeOriginal; String? timeZone; String? make; String? model; String? lens; float? f; float? mm; short? iso; float? exposureSeconds; float? lat; float? long; String? city; String? state; String? country; String? description; @ignore bool get hasCoordinates => latitude != null && longitude != null && latitude != 0 && longitude != 0; @ignore String get exposureTime { if (exposureSeconds == null) { return ""; } else if (exposureSeconds! < 1) { return "1/${(1.0 / exposureSeconds!).round()} s"; } else { return "${exposureSeconds!.toStringAsFixed(1)} s"; } } @ignore String get fNumber => f != null ? f!.toStringAsFixed(1) : ""; @ignore String get focalLength => mm != null ? mm!.toStringAsFixed(1) : ""; @ignore double? get latitude => lat; @ignore double? get longitude => long; ExifInfo.fromDto(ExifResponseDto dto) : fileSize = dto.fileSizeInByte, dateTimeOriginal = dto.dateTimeOriginal, timeZone = dto.timeZone, make = dto.make, model = dto.model, lens = dto.lensModel, f = dto.fNumber?.toDouble(), mm = dto.focalLength?.toDouble(), iso = dto.iso?.toInt(), exposureSeconds = _exposureTimeToSeconds(dto.exposureTime), lat = dto.latitude?.toDouble(), long = dto.longitude?.toDouble(), city = dto.city, state = dto.state, country = dto.country, description = dto.description; 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, }); ExifInfo copyWith({ Id? id, int? fileSize, DateTime? dateTimeOriginal, String? timeZone, String? make, String? model, String? lens, float? f, float? mm, short? iso, float? exposureSeconds, float? lat, float? long, String? city, String? state, String? country, String? description, }) => ExifInfo( id: id ?? this.id, fileSize: fileSize ?? this.fileSize, dateTimeOriginal: dateTimeOriginal ?? this.dateTimeOriginal, timeZone: timeZone ?? this.timeZone, make: make ?? this.make, model: model ?? this.model, lens: lens ?? this.lens, f: f ?? this.f, mm: mm ?? this.mm, iso: iso ?? this.iso, exposureSeconds: exposureSeconds ?? this.exposureSeconds, lat: lat ?? this.lat, long: long ?? this.long, city: city ?? this.city, state: state ?? this.state, country: country ?? this.country, description: description ?? this.description, ); @override bool operator ==(other) { if (other is! ExifInfo) return false; return id == other.id && fileSize == other.fileSize && dateTimeOriginal == other.dateTimeOriginal && timeZone == other.timeZone && make == other.make && model == other.model && lens == other.lens && f == other.f && mm == other.mm && iso == other.iso && exposureSeconds == other.exposureSeconds && lat == other.lat && long == other.long && city == other.city && state == other.state && country == other.country && description == other.description; } @override @ignore int get hashCode => id.hashCode ^ fileSize.hashCode ^ dateTimeOriginal.hashCode ^ timeZone.hashCode ^ make.hashCode ^ model.hashCode ^ lens.hashCode ^ f.hashCode ^ mm.hashCode ^ iso.hashCode ^ exposureSeconds.hashCode ^ lat.hashCode ^ long.hashCode ^ city.hashCode ^ state.hashCode ^ country.hashCode ^ description.hashCode; } double? _exposureTimeToSeconds(String? s) { if (s == null) { return null; } double? value = double.tryParse(s); if (value != null) { return value; } final parts = s.split("/"); if (parts.length == 2) { final numerator = double.tryParse(parts[0]); final denominator = double.tryParse(parts[1]); if (numerator != null && denominator != null) { return numerator / denominator; } } return null; }