128 lines
3.6 KiB
Dart
128 lines
3.6 KiB
Dart
// lib/remote/remote_models.dart
|
|
import 'url_utils.dart';
|
|
|
|
class RemotePhotoItem {
|
|
final String id;
|
|
final String name;
|
|
final String path;
|
|
final String? thub1, thub2;
|
|
final String? mimeType;
|
|
final int? width, height, sizeBytes;
|
|
final int? rotation;
|
|
final DateTime? takenAtUtc;
|
|
final double? lat, lng, alt;
|
|
final String? dataExifLegacy;
|
|
|
|
final String? user;
|
|
final int? durationMillis;
|
|
final RemoteLocation? location;
|
|
|
|
RemotePhotoItem({
|
|
required this.id,
|
|
required this.name,
|
|
required this.path,
|
|
this.thub1,
|
|
this.thub2,
|
|
this.mimeType,
|
|
this.width,
|
|
this.height,
|
|
this.rotation,
|
|
this.sizeBytes,
|
|
this.takenAtUtc,
|
|
this.lat,
|
|
this.lng,
|
|
this.alt,
|
|
this.dataExifLegacy,
|
|
this.user,
|
|
this.durationMillis,
|
|
this.location,
|
|
});
|
|
|
|
// URL completo costruito solo in fase di lettura
|
|
// String get uri => "https://prova.patachina.it/$path";
|
|
// Costruzione URL assoluto delegata a utility (in base alle impostazioni)
|
|
String absoluteUrl(String baseUrl) => buildAbsoluteUri(baseUrl, path).toString();
|
|
|
|
|
|
static DateTime? _tryParseIsoUtc(dynamic v) {
|
|
if (v == null) return null;
|
|
try { return DateTime.parse(v.toString()).toUtc(); } catch (_) { return null; }
|
|
}
|
|
|
|
static double? _toDouble(dynamic v) {
|
|
if (v == null) return null;
|
|
if (v is num) return v.toDouble();
|
|
return double.tryParse(v.toString());
|
|
}
|
|
|
|
static int? _toMillis(dynamic v) {
|
|
if (v == null) return null;
|
|
final num? n = (v is num) ? v : num.tryParse(v.toString());
|
|
if (n == null) return null;
|
|
return n >= 1000 ? n.toInt() : (n * 1000).toInt();
|
|
}
|
|
|
|
factory RemotePhotoItem.fromJson(Map<String, dynamic> j) {
|
|
final gps = j['gps'] as Map<String, dynamic>?;
|
|
final loc = j['location'] is Map<String, dynamic>
|
|
? RemoteLocation.fromJson(j['location'] as Map<String, dynamic>)
|
|
: null;
|
|
|
|
return RemotePhotoItem(
|
|
id: (j['id'] ?? j['name']).toString(),
|
|
name: (j['name'] ?? '').toString(),
|
|
path: (j['path'] ?? '').toString(),
|
|
thub1: j['thub1']?.toString(),
|
|
thub2: j['thub2']?.toString(),
|
|
mimeType: j['mime_type']?.toString(),
|
|
width: (j['width'] as num?)?.toInt(),
|
|
height: (j['height'] as num?)?.toInt(),
|
|
rotation: (j['rotation'] as num?)?.toInt(),
|
|
sizeBytes: (j['size_bytes'] as num?)?.toInt(),
|
|
takenAtUtc: _tryParseIsoUtc(j['taken_at']),
|
|
dataExifLegacy: j['data']?.toString(),
|
|
lat: gps != null ? _toDouble(gps['lat']) : null,
|
|
lng: gps != null ? _toDouble(gps['lng']) : null,
|
|
alt: gps != null ? _toDouble(gps['alt']) : null,
|
|
user: j['user']?.toString(),
|
|
durationMillis: _toMillis(j['duration']),
|
|
location: loc,
|
|
);
|
|
}
|
|
}
|
|
|
|
class RemoteLocation {
|
|
final String? continent;
|
|
final String? country;
|
|
final String? region;
|
|
final String? postcode;
|
|
final String? city;
|
|
final String? countyCode;
|
|
final String? address;
|
|
final String? timezone;
|
|
final String? timeOffset;
|
|
|
|
RemoteLocation({
|
|
this.continent,
|
|
this.country,
|
|
this.region,
|
|
this.postcode,
|
|
this.city,
|
|
this.countyCode,
|
|
this.address,
|
|
this.timezone,
|
|
this.timeOffset,
|
|
});
|
|
|
|
factory RemoteLocation.fromJson(Map<String, dynamic> j) => RemoteLocation(
|
|
continent: j['continent']?.toString(),
|
|
country: j['country']?.toString(),
|
|
region: j['region']?.toString(),
|
|
postcode: j['postcode']?.toString(),
|
|
city: j['city']?.toString(),
|
|
countyCode:j['county_code']?.toString(),
|
|
address: j['address']?.toString(),
|
|
timezone: j['timezone']?.toString(),
|
|
timeOffset:j['time']?.toString(),
|
|
);
|
|
}
|