manager-app/lib/Screens/Resources/resource_formatting.dart

118 lines
4.2 KiB
Dart

import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:manager_app/l10n/app_localizations.dart';
import 'package:manager_api_new/api.dart';
/// Extension réelle d'une ressource, dans l'ordre : le nom de fichier stocké s'il
/// existe, sinon celle que le type impose. Le téléchargement forçait `.json` pour
/// tout le monde — un PNG arrivait en `label.json`, illisible sans renommage.
const Map<ResourceType, String> _extensionByType = {
ResourceType.Image: '.jpg',
ResourceType.ImageUrl: '.jpg',
ResourceType.Audio: '.mp3',
ResourceType.Video: '.mp4',
ResourceType.VideoUrl: '.mp4',
ResourceType.Pdf: '.pdf',
ResourceType.Json: '.json',
ResourceType.JsonUrl: '.json',
};
/// Type d'une ressource locale, déduit de son extension. Un seul endroit : le
/// dialogue d'ajout l'affiche en pastille, `create()` l'enregistre. Avant, le
/// dialogue posait `ResourceType.Image` pour tout fichier et `create()` le
/// recalculait — à la lecture, un MP3 semblait parti pour être une image.
ResourceType? resourceTypeForExtension(String? extension) {
switch (extension?.toLowerCase()) {
case 'jpg':
case 'jpeg':
case 'png':
case 'gif':
return ResourceType.Image;
case 'mp3':
return ResourceType.Audio;
case 'mp4':
case 'webm':
return ResourceType.Video;
case 'pdf':
return ResourceType.Pdf;
case 'json':
return ResourceType.Json;
default:
return null;
}
}
String mimeTypeForExtension(String? extension) {
switch (extension?.toLowerCase()) {
case 'jpg':
case 'jpeg':
return 'image/jpeg';
case 'png':
return 'image/png';
case 'gif':
return 'image/gif';
case 'mp3':
return 'audio/mpeg';
case 'mp4':
return 'video/mp4';
case 'webm':
return 'video/webm';
case 'pdf':
return 'application/pdf';
case 'json':
return 'application/json';
default:
return 'application/octet-stream';
}
}
/// Libellé lisible d'un type, dans la langue du manager.
String resourceTypeLabel(AppLocalizations l, ResourceType? type) {
switch (type) {
case ResourceType.Image: return l.resourceTypeImage;
case ResourceType.ImageUrl: return l.resourceTypeImageUrl;
case ResourceType.Video: return l.resourceTypeVideo;
case ResourceType.VideoUrl: return l.resourceTypeVideoUrl;
case ResourceType.Audio: return l.resourceTypeAudio;
case ResourceType.Pdf: return l.resourceTypePdf;
case ResourceType.Json: return l.resourceTypeJson;
case ResourceType.JsonUrl: return l.resourceTypeJsonUrl;
default: return '';
}
}
String downloadFileNameFor(ResourceDTO resource) {
final fileName = resource.fileName;
if (fileName != null && fileName.trim().isNotEmpty) {
return fileName;
}
final label = (resource.label ?? 'ressource').trim();
final extension = _extensionByType[resource.type] ?? '';
return label.toLowerCase().endsWith(extension) ? label : '$label$extension';
}
/// L'unité suit la langue : « Ko » en français, « KB » en anglais.
String formatBytes(BuildContext context, int? bytes) {
final l = AppLocalizations.of(context)!;
if (bytes == null || bytes <= 0) return '';
if (bytes < 1024) return l.mediaSizeBytes('$bytes');
if (bytes < 1024 * 1024) return l.mediaSizeKilobytes((bytes / 1024).toStringAsFixed(0));
return l.mediaSizeMegabytes((bytes / (1024 * 1024)).toStringAsFixed(1));
}
/// Mois et dates passent par `intl` avec la locale courante — une liste de mois
/// écrite en dur ne se traduit pas et ne suit pas l'ordre jour/mois de l'anglais.
String formatMonth(BuildContext context, DateTime? date) {
if (date == null) return AppLocalizations.of(context)!.mediaNoDate;
final locale = Localizations.localeOf(context).toString();
final label = DateFormat.yMMMM(locale).format(date);
return label.isEmpty ? label : label[0].toUpperCase() + label.substring(1);
}
String formatDate(BuildContext context, DateTime? date) => date == null
? ''
: DateFormat.yMd(Localizations.localeOf(context).toString()).format(date);
String monthKey(DateTime? date) =>
date == null ? '0000-00' : '${date.year}-${date.month.toString().padLeft(2, '0')}';