142 lines
4.7 KiB
Dart
142 lines
4.7 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:manager_app/Components/resource_picker.dart';
|
|
import 'package:manager_app/Screens/Resources/resource_formatting.dart';
|
|
import 'package:manager_app/app_context.dart';
|
|
import 'package:manager_app/constants.dart';
|
|
import 'package:manager_app/l10n/app_localizations.dart';
|
|
|
|
/// Dialogue d'ajout d'une ressource.
|
|
///
|
|
/// Un seul corps, pas deux onglets : « Local » / « En ligne » imposait une question
|
|
/// technique — où vivent les octets — avant que l'utilisateur ait rien choisi. Une
|
|
/// zone de dépôt, et dessous une ligne « ou coller une URL » qui se déplie.
|
|
///
|
|
/// Rend la liste des entrées choisies, ou `null` si le dialogue est annulé.
|
|
Future<List<PickedResource>?> showNewResource(
|
|
AppContext appContext, BuildContext context) async {
|
|
final picked = <PickedResource>[];
|
|
|
|
return showDialog<List<PickedResource>>(
|
|
context: context,
|
|
builder: (BuildContext context) => _NewResourceDialog(picked: picked),
|
|
);
|
|
}
|
|
|
|
class _NewResourceDialog extends StatefulWidget {
|
|
final List<PickedResource> picked;
|
|
const _NewResourceDialog({required this.picked});
|
|
|
|
@override
|
|
State<_NewResourceDialog> createState() => _NewResourceDialogState();
|
|
}
|
|
|
|
class _NewResourceDialogState extends State<_NewResourceDialog> {
|
|
int get _totalBytes =>
|
|
widget.picked.fold<int>(0, (sum, entry) => sum + entry.sizeBytes);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final l = AppLocalizations.of(context)!;
|
|
|
|
return Dialog(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(kRadiusShell),
|
|
side: const BorderSide(color: kLine),
|
|
),
|
|
clipBehavior: Clip.antiAlias,
|
|
child: SizedBox(
|
|
width: 560,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
_header(l),
|
|
Flexible(
|
|
child: SingleChildScrollView(
|
|
padding: const EdgeInsets.fromLTRB(kSpace6, 0, kSpace6, kSpace4),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
ResourcePicker(
|
|
picked: widget.picked,
|
|
onChanged: () => setState(() {}),
|
|
),
|
|
if (widget.picked.isNotEmpty) _totals(l),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
_footer(l),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _header(AppLocalizations l) {
|
|
return Padding(
|
|
padding: const EdgeInsets.fromLTRB(kSpace6, kSpace5, kSpace4, kSpace4),
|
|
child: Row(
|
|
children: [
|
|
Expanded(child: Text(l.mediaAddTitle, style: kTitleCard)),
|
|
IconButton(
|
|
icon: const Icon(Icons.close, size: 18, color: kInk3),
|
|
splashRadius: 16,
|
|
tooltip: l.close,
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _totals(AppLocalizations l) {
|
|
return Padding(
|
|
padding: const EdgeInsets.only(top: kSpace4),
|
|
child: Text(
|
|
l.mediaSelectedTotal(widget.picked.length, formatBytes(context, _totalBytes)),
|
|
style: kTextHint,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _footer(AppLocalizations l) {
|
|
// Désactivé plutôt qu'expliqué : l'ancien dialogue acceptait le clic à vide,
|
|
// puis affichait une notification orange « aucun fichier chargé ».
|
|
final canAdd = widget.picked.isNotEmpty;
|
|
|
|
return Container(
|
|
padding: const EdgeInsets.all(kSpace4),
|
|
decoration: const BoxDecoration(
|
|
color: kSurface2,
|
|
border: Border(top: BorderSide(color: kLineSoft)),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: [
|
|
TextButton(
|
|
onPressed: () => Navigator.of(context).pop(),
|
|
child: Text(l.cancel,
|
|
style: const TextStyle(fontSize: 13, color: kInk2)),
|
|
),
|
|
const SizedBox(width: kSpace2),
|
|
FilledButton(
|
|
onPressed:
|
|
canAdd ? () => Navigator.pop(context, widget.picked) : null,
|
|
style: FilledButton.styleFrom(
|
|
backgroundColor: kPrimaryColor,
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: kSpace5, vertical: kSpace3),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(kRadiusPill)),
|
|
),
|
|
child: Text(l.mediaAddCount(widget.picked.length),
|
|
style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w600)),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|