// 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 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 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), ), ), ), ), ); }