You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 line
5.5KB

  1. // lib/presentation/screens/post_refinement/post_refinement_screen.dart
  2. import 'package:flutter/material.dart';
  3. // --- CORRECTION 1 : IMPORTER LE REPOSITORY ---
  4. import '../../../repositories/ai_repository.dart';
  5. import '../../../routes/app_routes.dart';
  6. import '../../widgets/creation_flow_layout.dart';
  7. import '../post_preview/post_preview_screen.dart';
  8. // L'import de 'ollama_service.dart' est supprimé.
  9. // --- CORRECTION 2 : DÉFINIR UNE CLASSE D'ARGUMENTS PROPRE ---
  10. class PostRefinementScreenArguments {
  11. PostRefinementScreenArguments({
  12. required this.initialText,
  13. required this.imageBase64,
  14. required this.aiRepository,
  15. });
  16. final String initialText;
  17. final String imageBase64;
  18. final AiRepository aiRepository;
  19. }
  20. class PostRefinementScreen extends StatefulWidget {
  21. const PostRefinementScreen({
  22. required this.arguments, super.key,
  23. });
  24. // Le constructeur attend maintenant la classe d'arguments.
  25. final PostRefinementScreenArguments arguments;
  26. @override
  27. State<PostRefinementScreen> createState() => _PostRefinementScreenState();
  28. }
  29. class _PostRefinementScreenState extends State<PostRefinementScreen> {
  30. late final TextEditingController _postTextController;
  31. final TextEditingController _promptController = TextEditingController();
  32. bool _isImproving = false;
  33. @override
  34. void initState() {
  35. super.initState();
  36. // On initialise le texte depuis les arguments reçus.
  37. _postTextController = TextEditingController(text: widget.arguments.initialText);
  38. }
  39. @override
  40. void dispose() {
  41. _postTextController.dispose();
  42. _promptController.dispose();
  43. super.dispose();
  44. }
  45. // --- CORRECTION 3 : UTILISER LE REPOSITORY POUR L'AMÉLIORATION ---
  46. Future<void> _handleImproveWithAI() async {
  47. final instruction = _promptController.text;
  48. if (instruction.isEmpty || _isImproving) return;
  49. if (!mounted) return;
  50. setState(() => _isImproving = true);
  51. try {
  52. // On appelle la méthode du Repository, qui se chargera de déléguer au bon service.
  53. final improvedText = await widget.arguments.aiRepository.improvePostText(
  54. originalText: _postTextController.text,
  55. userInstruction: instruction,
  56. );
  57. if (mounted) {
  58. setState(() {
  59. _postTextController.text = improvedText;
  60. _promptController.clear();
  61. });
  62. }
  63. } catch (e) {
  64. if (mounted) {
  65. ScaffoldMessenger.of(context).showSnackBar(SnackBar(
  66. content: Text("Erreur d'amélioration : ${e.toString()}"),
  67. backgroundColor: Colors.red));
  68. }
  69. } finally {
  70. if (mounted) {
  71. setState(() => _isImproving = false);
  72. }
  73. }
  74. }
  75. // --- CORRECTION 4 : NAVIGATION PROPRE VERS L'APERÇU FINAL ---
  76. // --- CORRECTION APPLIQUÉE ICI ---
  77. void _navigateToPreview() {
  78. Navigator.pushNamed(
  79. context,
  80. AppRoutes.postPreview,
  81. // Au lieu d'envoyer une Map, on crée l'objet PostPreviewArguments
  82. // que l'écran suivant attend.
  83. arguments: PostPreviewArguments(
  84. imageBase64: widget.arguments.imageBase64,
  85. text: _postTextController.text,
  86. aiRepository: widget.arguments.aiRepository,
  87. ),
  88. );
  89. }
  90. @override
  91. Widget build(BuildContext context) {
  92. // Le widget build est INCHANGÉ dans sa structure.
  93. return CreationFlowLayout( // Ajout du layout de flux
  94. currentStep: 5, // C'est la 6ème étape
  95. title: '5. Affinage du texte',
  96. child: Scaffold(
  97. appBar: AppBar(
  98. title: const Text('Affiner le post'),
  99. actions: [
  100. FilledButton.tonal(
  101. onPressed: _navigateToPreview,
  102. child: const Text('Valider'),
  103. ),
  104. const SizedBox(width: 16),
  105. ],
  106. ),
  107. body: SingleChildScrollView(
  108. padding: const EdgeInsets.all(16),
  109. child: Column(
  110. crossAxisAlignment: CrossAxisAlignment.stretch,
  111. children: [
  112. TextField(
  113. controller: _postTextController,
  114. maxLines: 8,
  115. decoration: const InputDecoration(
  116. labelText: 'Texte du post',
  117. border: OutlineInputBorder(),
  118. alignLabelWithHint: true,
  119. ),
  120. ),
  121. const SizedBox(height: 24),
  122. const Row(children: [
  123. Expanded(child: Divider()),
  124. Padding(
  125. padding: EdgeInsets.symmetric(horizontal: 8),
  126. child: Text("Améliorer avec l'IA"),
  127. ),
  128. Expanded(child: Divider()),
  129. ]),
  130. const SizedBox(height: 16),
  131. TextField(
  132. controller: _promptController,
  133. decoration: const InputDecoration(
  134. hintText: 'Ex: ajoute plus de détails, rends-le plus fun...',
  135. border: OutlineInputBorder(),
  136. ),
  137. ),
  138. const SizedBox(height: 16),
  139. FilledButton.icon(
  140. onPressed: _handleImproveWithAI,
  141. icon: _isImproving
  142. ? const SizedBox(
  143. width: 20,
  144. height: 20,
  145. child: CircularProgressIndicator(
  146. color: Colors.white, strokeWidth: 2))
  147. : const Icon(Icons.auto_awesome),
  148. label: const Text("Lancer l'amélioration"),
  149. style: FilledButton.styleFrom(
  150. padding: const EdgeInsets.symmetric(vertical: 16)),
  151. ),
  152. ],
  153. ),
  154. ),
  155. ),
  156. );
  157. }
  158. }