feat: édition rapide des accessoires créant une nouvelle arme/config pour différencier les stats
This commit is contained in:
@@ -152,7 +152,24 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text('Options & Personnalisation', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Expanded(
|
||||
child: Text('Options & Personnalisation', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
|
||||
),
|
||||
IconButton(
|
||||
tooltip: 'Modifier les accessoires (crée une nouvelle configuration)',
|
||||
icon: const Icon(Icons.edit, color: Colors.white, size: 18),
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: AppTheme.primaryColor,
|
||||
padding: const EdgeInsets.all(8),
|
||||
minimumSize: const Size(36, 36),
|
||||
),
|
||||
onPressed: () => _showEditAccessoriesDialog(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Divider(),
|
||||
_buildInfoRow('Optique / Lunette', _weapon.optic ?? 'Mire fer'),
|
||||
_buildInfoRow('Modérateur / Silencieux', _weapon.silencer ?? 'Aucun'),
|
||||
@@ -374,6 +391,112 @@ class _WeaponDetailScreenState extends State<WeaponDetailScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
// Édition rapide des accessoires uniquement. Comme la qualité de tir dépend
|
||||
// fortement des accessoires, on ne modifie PAS l'arme existante : on crée une
|
||||
// nouvelle arme (même modèle, accessoires différents) dans l'armurerie afin de
|
||||
// pouvoir comparer les scores selon la configuration utilisée.
|
||||
void _showEditAccessoriesDialog(BuildContext context) async {
|
||||
final opticController = TextEditingController(text: _weapon.optic);
|
||||
final silencerController = TextEditingController(text: _weapon.silencer);
|
||||
final triggerController = TextEditingController(text: _weapon.trigger);
|
||||
final customNameController = TextEditingController(text: _weapon.customName);
|
||||
|
||||
final result = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: const Text('Modifier les accessoires'),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
'Une nouvelle arme sera créée dans l\'armurerie avec ces accessoires, '
|
||||
'pour pouvoir comparer les scores selon la configuration.',
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
_autoScrollOnFocus(TextField(
|
||||
controller: opticController,
|
||||
decoration: const InputDecoration(labelText: 'Optique / Lunette', hintText: 'ex: Holosun 507C'),
|
||||
)),
|
||||
_autoScrollOnFocus(TextField(
|
||||
controller: silencerController,
|
||||
decoration: const InputDecoration(labelText: 'Modérateur / Silencieux'),
|
||||
)),
|
||||
_autoScrollOnFocus(TextField(
|
||||
controller: triggerController,
|
||||
decoration: const InputDecoration(labelText: 'Détente / Trigger'),
|
||||
)),
|
||||
_autoScrollOnFocus(TextField(
|
||||
controller: customNameController,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Surnom de la configuration',
|
||||
hintText: 'ex: Echelon + Holosun',
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.pop(context, false), child: const Text('Annuler')),
|
||||
ElevatedButton(onPressed: () => Navigator.pop(context, true), child: const Text('Créer la configuration')),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (result != true) return;
|
||||
|
||||
final newOptic = opticController.text.isEmpty ? null : opticController.text;
|
||||
final newSilencer = silencerController.text.isEmpty ? null : silencerController.text;
|
||||
final newTrigger = triggerController.text.isEmpty ? null : triggerController.text;
|
||||
var newCustomName = customNameController.text.isEmpty ? null : customNameController.text;
|
||||
|
||||
// Rien à faire si aucun accessoire n'a changé.
|
||||
final unchanged = newOptic == _weapon.optic &&
|
||||
newSilencer == _weapon.silencer &&
|
||||
newTrigger == _weapon.trigger;
|
||||
if (unchanged) {
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Aucun accessoire modifié, aucune configuration créée.')),
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Génère un surnom par défaut décrivant la config si l'utilisateur n'en a pas saisi.
|
||||
if (newCustomName == null) {
|
||||
final accessories = [newOptic, newSilencer, newTrigger]
|
||||
.where((a) => a != null && a.isNotEmpty)
|
||||
.join(' / ');
|
||||
newCustomName = accessories.isEmpty ? null : '${_weapon.name} ($accessories)';
|
||||
}
|
||||
|
||||
final repository = context.read<SessionRepository>();
|
||||
final newWeapon = await repository.addWeapon(
|
||||
name: _weapon.name,
|
||||
type: _weapon.type,
|
||||
caliber: _weapon.caliber,
|
||||
magazineCount: _weapon.magazineCount,
|
||||
magazineCapacity: _weapon.magazineCapacity,
|
||||
notes: _weapon.notes,
|
||||
optic: newOptic,
|
||||
silencer: newSilencer,
|
||||
trigger: newTrigger,
|
||||
customName: newCustomName,
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text('Nouvelle configuration créée : ${newWeapon.displayName}')),
|
||||
);
|
||||
// On bascule sur la nouvelle arme pour que les sessions suivantes y soient rattachées.
|
||||
Navigator.pushReplacement(
|
||||
context,
|
||||
MaterialPageRoute(builder: (_) => WeaponDetailScreen(weapon: newWeapon)),
|
||||
);
|
||||
}
|
||||
|
||||
void _showAddMaintenanceDialog(BuildContext context) async {
|
||||
final descController = TextEditingController();
|
||||
MaintenanceType selectedType = MaintenanceType.cleaning;
|
||||
|
||||
Reference in New Issue
Block a user