import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../servisler/wangp/wangp_baslatici.dart'; /// WanGP durum kartı — segment WanGP motoruna geçirildiğinde Inspector'da çıkar. /// /// **Önemli:** Üretim WanGP'nin CLI moduyla yapılır (`wgp.py --process settings.json`). /// Gradio sunucusu (port 7861) **zorunlu değil** — sadece UI üzerinden manuel /// test/debug yapmak isteyenler için opsiyoneldir. /// /// Kart: /// - CLI hazırsa → yeşil "Hazır" rozeti + opsiyonel sunucu durumu /// - Sunucu kapalıysa → "Gradio UI'sını başlat (opsiyonel)" linki class WanGpBaslatKarti extends ConsumerWidget { /// `true` → CLI hazırsa hiç gösterme (sade UI) /// `false` → her durumda küçük bir bilgi rozeti göster (varsayılan) final bool sadeceKapaliyken; const WanGpBaslatKarti({super.key, this.sadeceKapaliyken = false}); @override Widget build(BuildContext context, WidgetRef ref) { final durum = ref.watch(wangpProvider); final theme = Theme.of(context); final cs = theme.colorScheme; final sunucuAcik = durum.calisiyor; if (sadeceKapaliyken && sunucuAcik) return const SizedBox.shrink(); return Card( margin: const EdgeInsets.symmetric(vertical: 8), color: cs.primaryContainer.withValues(alpha: 0.18), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: BorderSide( color: cs.primary.withValues(alpha: 0.3), width: 1, ), ), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( children: [ Container( width: 10, height: 10, decoration: BoxDecoration( color: Colors.green, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: Colors.green.withValues(alpha: 0.55), blurRadius: 6, spreadRadius: 0.5, ), ], ), ), const SizedBox(width: 10), Expanded( child: Text( 'WanGP CLI hazır', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w700, color: cs.onSurface, ), ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), decoration: BoxDecoration( color: Colors.green.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(8), ), child: Text( 'CLI MODE', style: theme.textTheme.labelSmall?.copyWith( color: Colors.green.shade700, fontWeight: FontWeight.w700, letterSpacing: 0.5, ), ), ), ], ), const SizedBox(height: 6), Text( '✓ "Üret" butonuna bas → arka planda otomatik çalışır. ' 'Hiçbir şey açmana gerek yok.', style: theme.textTheme.bodySmall?.copyWith( color: cs.onSurfaceVariant, fontWeight: FontWeight.w500), ), const SizedBox(height: 4), // İleri (opsiyonel): Gradio sunucusu durumu — sadece bilgi Theme( data: theme.copyWith(dividerColor: Colors.transparent), child: ExpansionTile( tilePadding: EdgeInsets.zero, childrenPadding: EdgeInsets.zero, dense: true, visualDensity: VisualDensity.compact, title: Text( 'İleri (opsiyonel)', style: theme.textTheme.labelSmall?.copyWith( color: cs.outline, fontWeight: FontWeight.w600), ), children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 6), decoration: BoxDecoration( color: cs.surfaceContainerHighest .withValues(alpha: 0.5), borderRadius: BorderRadius.circular(6), ), child: Row( children: [ Icon( sunucuAcik ? Icons.public : Icons.public_off_outlined, size: 14, color: sunucuAcik ? Colors.green : cs.outline, ), const SizedBox(width: 6), Expanded( child: Text( sunucuAcik ? 'Gradio UI açık · port 7861 (manuel test için)' : 'Gradio UI kapalı · render için GEREKMİYOR', style: theme.textTheme.labelSmall?.copyWith( color: sunucuAcik ? Colors.green.shade700 : cs.outline, ), ), ), if (!sunucuAcik) TextButton( style: TextButton.styleFrom( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 0), minimumSize: const Size(0, 24), ), onPressed: () => ref.read(wangpProvider.notifier).baslat(), child: const Text('Aç', style: TextStyle(fontSize: 11)), ), ], ), ), ], ), ), if (durum.hata != null) ...[ const SizedBox(height: 6), Text( durum.hata!, style: theme.textTheme.labelSmall?.copyWith( color: cs.error, fontStyle: FontStyle.italic, ), ), ], ], ), ), ).animate().fadeIn(duration: 200.ms); } }