import 'dart:convert'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:island/models/file.dart'; import 'package:island/utils/format.dart'; import 'package:island/widgets/alert.dart'; import 'package:island/widgets/content/sheet.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:styled_widget/styled_widget.dart'; class FileInfoSheet extends StatelessWidget { final SnCloudFile item; const FileInfoSheet({super.key, required this.item}); @override Widget build(BuildContext context) { final theme = Theme.of(context); final exifData = item.fileMeta?['exif'] as Map? ?? {}; return SheetScaffold( titleText: 'fileInfoTitle'.tr(), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Text('mimeType').tr(), Text( item.mimeType ?? 'unknown'.tr(), maxLines: 1, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), ), SizedBox(height: 28, child: const VerticalDivider()), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Text('fileSize').tr(), Text( formatFileSize(item.size), style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), ), if (item.hash != null) SizedBox(height: 28, child: const VerticalDivider()), if (item.hash != null) Expanded( child: GestureDetector( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Text('fileHash').tr(), Text( '${item.hash!.substring(0, 6)}...', style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), ], ), onLongPress: () { Clipboard.setData(ClipboardData(text: item.hash!)); showSnackBar('fileHashCopied'.tr()); }, ), ), ], ).padding(horizontal: 24, vertical: 16), const Divider(height: 1), ListTile( leading: const Icon(Symbols.tag), title: Text('ID').tr(), subtitle: Text( item.id, maxLines: 1, overflow: TextOverflow.ellipsis, ), contentPadding: EdgeInsets.symmetric(horizontal: 24), trailing: IconButton( icon: const Icon(Icons.copy), onPressed: () { Clipboard.setData(ClipboardData(text: item.id)); showSnackBar('fileIdCopied'.tr()); }, ), ), ListTile( leading: const Icon(Symbols.file_present), title: Text('Name').tr(), subtitle: Text( item.name, maxLines: 1, overflow: TextOverflow.ellipsis, ), contentPadding: EdgeInsets.symmetric(horizontal: 24), trailing: IconButton( icon: const Icon(Icons.copy), onPressed: () { Clipboard.setData(ClipboardData(text: item.name)); showSnackBar('fileNameCopied'.tr()); }, ), ), if (item.pool != null) ListTile( leading: const Icon(Symbols.calendar_today), title: Text('File Pool').tr(), subtitle: Text( item.pool!.name, maxLines: 1, overflow: TextOverflow.ellipsis, ), contentPadding: EdgeInsets.symmetric(horizontal: 24), trailing: IconButton( icon: const Icon(Icons.copy), onPressed: () { Clipboard.setData(ClipboardData(text: item.pool!.id)); showSnackBar('fileNameCopied'.tr()); }, ), ), if (exifData.isNotEmpty) ...[ const Divider(height: 1), Theme( data: theme.copyWith(dividerColor: Colors.transparent), child: ExpansionTile( tilePadding: const EdgeInsets.symmetric(horizontal: 24), title: Text( 'exifData'.tr(), style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...exifData.entries.map( (entry) => ListTile( dense: true, contentPadding: EdgeInsets.symmetric( horizontal: 24, ), title: Text( entry.key.contains('-') ? entry.key.split('-').last : entry.key, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ).bold(), subtitle: Text( '${entry.value}'.isNotEmpty ? '${entry.value}' : 'N/A', style: theme.textTheme.bodyMedium, ), onTap: () { Clipboard.setData( ClipboardData(text: '${entry.value}'), ); showSnackBar('valueCopied'.tr()); }, ), ), ], ), ], ), ), ], if (item.fileMeta != null && item.fileMeta!.isNotEmpty) ...[ const Divider(height: 1), Theme( data: theme.copyWith(dividerColor: Colors.transparent), child: ExpansionTile( tilePadding: const EdgeInsets.symmetric(horizontal: 24), title: Text( 'fileMetadata'.tr(), style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...item.fileMeta!.entries.map( (entry) => ListTile( dense: true, contentPadding: EdgeInsets.symmetric( horizontal: 24, ), title: Text( entry.key, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ).bold(), subtitle: Text( jsonEncode(entry.value), style: theme.textTheme.bodyMedium, maxLines: 3, overflow: TextOverflow.ellipsis, ), onTap: () { Clipboard.setData( ClipboardData(text: jsonEncode(entry.value)), ); showSnackBar('valueCopied'.tr()); }, ), ), ], ), ], ), ), ], if (item.userMeta != null && item.userMeta!.isNotEmpty) ...[ const Divider(height: 1), Theme( data: theme.copyWith(dividerColor: Colors.transparent), child: ExpansionTile( tilePadding: const EdgeInsets.symmetric(horizontal: 24), title: Text( 'userMetadata'.tr(), style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, ), ), children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ...item.userMeta!.entries.map( (entry) => ListTile( dense: true, contentPadding: EdgeInsets.symmetric( horizontal: 24, ), title: Text( entry.key, style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w500, ), ).bold(), subtitle: Text( jsonEncode(entry.value), style: theme.textTheme.bodyMedium, maxLines: 3, overflow: TextOverflow.ellipsis, ), onTap: () { Clipboard.setData( ClipboardData(text: jsonEncode(entry.value)), ); showSnackBar('valueCopied'.tr()); }, ), ), ], ), ], ), ), ], const SizedBox(height: 16), ], ), ), ); } }