70 lines
2.3 KiB
Dart
70 lines
2.3 KiB
Dart
// lib/remote/remote_view_helpers.dart
|
|
import 'package:flutter/material.dart';
|
|
import 'remote_http.dart';
|
|
import 'package:aves/model/entry/entry.dart';
|
|
|
|
/// Un entry è "remoto" se origin==1
|
|
bool isRemote(AvesEntry e) => e.origin == 1;
|
|
|
|
/// Heuristics base per capire se è video (MIME o estensione)
|
|
bool isVideo(AvesEntry e) {
|
|
final mt = (e.sourceMimeType ?? '').toLowerCase();
|
|
final p = (e.remotePath ?? e.path ?? '').toLowerCase();
|
|
return mt.startsWith('video/') ||
|
|
p.endsWith('.mp4') || p.endsWith('.mov') ||
|
|
p.endsWith('.webm') || p.endsWith('.mkv') || p.endsWith('.m4v');
|
|
}
|
|
|
|
/// Normalizza la rotazione a {0,90,180,270}.
|
|
/// Se non presente o non valida → 0.
|
|
int rotationDegOf(AvesEntry e) {
|
|
final raw = e.sourceRotationDegrees ?? 0;
|
|
final n = ((raw % 360) + 360) % 360;
|
|
if (n % 90 != 0) return 0;
|
|
return n;
|
|
}
|
|
|
|
/// Aspect ratio "effettivo" per il layout:
|
|
/// se la rotazione è 90/270 → scambia width/height.
|
|
double effectiveAspectRatio(AvesEntry e) {
|
|
final w = (e.width ?? 0).toDouble();
|
|
final h = (e.height ?? 0).toDouble();
|
|
if (w <= 0 || h <= 0) return 1.0; // fallback sicuro
|
|
final rot = rotationDegOf(e);
|
|
final swap = rot == 90 || rot == 270;
|
|
return swap ? (h / w) : (w / h);
|
|
}
|
|
|
|
/// Versione compatibile (chiama quella con rotazione).
|
|
Future<Widget> remoteImageFull(AvesEntry e) => remoteImageFullWithRotate(e);
|
|
|
|
/// Mostra l'immagine remota rispettando rotazione e aspect ratio.
|
|
/// - Usa AspectRatio per non "schiacciare" l'immagine.
|
|
/// - Usa RotatedBox (rotazioni a quarti di giro) per non perdere qualità.
|
|
/// - Carica via HTTP + Bearer (RemoteHttp).
|
|
Future<Widget> remoteImageFullWithRotate(AvesEntry e) async {
|
|
final url = RemoteHttp.absUrl(e.remotePath ?? e.path);
|
|
final hdr = await RemoteHttp.headers();
|
|
if (url.isEmpty) return const Icon(Icons.broken_image, size: 64);
|
|
|
|
final rot = rotationDegOf(e);
|
|
final quarterTurns = (rot ~/ 90) % 4; // 0..3
|
|
|
|
return Center(
|
|
child: AspectRatio(
|
|
aspectRatio: effectiveAspectRatio(e),
|
|
child: InteractiveViewer(
|
|
maxScale: 5,
|
|
child: RotatedBox(
|
|
quarterTurns: quarterTurns,
|
|
child: Image.network(
|
|
url,
|
|
fit: BoxFit.contain,
|
|
headers: hdr,
|
|
errorBuilder: (_, __, ___) => const Icon(Icons.broken_image, size: 64),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|