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.

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