import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../app/tema.dart'; import '../cekirdek/sabitler.dart'; import 'comfy_ws.dart'; /// ComfyUI sürecini app içinden başlat/durdur/yeniden başlat. abstract final class ComfyBaslatici { static void baslat() { final bat = File(Sabitler.comfyBaslatBat); if (!bat.existsSync()) return; Process.start( 'cmd', ['/c', 'start', 'FikoYT-ComfyUI', '/min', Sabitler.comfyBaslatBat], workingDirectory: bat.parent.path, mode: ProcessStartMode.detached, ); } /// ComfyUI python sürecini sonlandırır (port 8188 dinleyeni öldürür). static Future durdur() async { // 8188 portunu dinleyen PID'i bul ve öldür. try { final r = await Process.run('cmd', [ '/c', 'for /f "tokens=5" %a in (\'netstat -ano ^| findstr :8188 ^| findstr LISTENING\') do taskkill /F /PID %a' ]); // Yedek: ComfyUI başlık pencerelerini de kapat. await Process.run('cmd', ['/c', 'taskkill /F /FI "WINDOWTITLE eq FikoYT-ComfyUI*"']); if (r.exitCode != 0) {/* sessiz */} } catch (_) {} } static Future yenidenBaslat() async { await durdur(); await Future.delayed(const Duration(seconds: 2)); baslat(); } } /// Sidebar altındaki ComfyUI bağlantı rozeti + başlat/durdur/yeniden başlat. class ComfyDurumRozeti extends ConsumerWidget { const ComfyDurumRozeti({super.key, this.genis = true}); final bool genis; @override Widget build(BuildContext context, WidgetRef ref) { final durum = ref.watch(comfyBaglantiProvider).valueOrNull ?? ComfyBaglanti.kopuk; final (renk, etiket, ikon) = switch (durum) { ComfyBaglanti.bagli => (FikoRenkler.neonYesil, 'ComfyUI Bağlı', Icons.bolt), ComfyBaglanti.baglaniyor => ( FikoRenkler.neonAmber, 'Bağlanıyor...', Icons.sync ), ComfyBaglanti.kopuk => ( Theme.of(context).colorScheme.error, 'ComfyUI Kapalı', Icons.power_off ), }; final rozet = AnimatedContainer( duration: Sabitler.animOrta, padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8), decoration: BoxDecoration( color: renk.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(10), border: Border.all(color: renk.withValues(alpha: 0.45)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(ikon, size: 16, color: renk), if (genis) ...[ const SizedBox(width: 8), Flexible( child: Text(etiket, overflow: TextOverflow.ellipsis, style: TextStyle( color: renk, fontSize: 12, fontWeight: FontWeight.w600)), ), const SizedBox(width: 4), Icon(Icons.expand_more, size: 14, color: renk.withValues(alpha: 0.7)), ], ], ), ); return MenuAnchor( builder: (context, ctrl, _) => InkWell( borderRadius: BorderRadius.circular(10), onTap: () => ctrl.isOpen ? ctrl.close() : ctrl.open(), child: rozet, ), menuChildren: [ if (durum == ComfyBaglanti.kopuk) MenuItemButton( leadingIcon: const Icon(Icons.play_arrow, size: 17, color: FikoRenkler.neonYesil), onPressed: ComfyBaslatici.baslat, child: const Text('ComfyUI\'yi Başlat'), ) else ...[ MenuItemButton( leadingIcon: const Icon(Icons.restart_alt, size: 17), onPressed: ComfyBaslatici.yenidenBaslat, child: const Text('Yeniden Başlat'), ), MenuItemButton( leadingIcon: const Icon(Icons.stop_circle_outlined, size: 17, color: Color(0xFFFF5370)), onPressed: ComfyBaslatici.durdur, child: const Text('Durdur'), ), ], const Divider(), MenuItemButton( leadingIcon: const Icon(Icons.folder_open, size: 17), onPressed: () => Process.start( 'explorer', [File(Sabitler.comfyBaslatBat).parent.path], mode: ProcessStartMode.detached), child: const Text('ComfyUI klasörünü aç'), ), ], ); } }