import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../durum/proje_durumu.dart'; import '../modeller/job.dart'; import '../servisler/job_orkestratoru.dart'; import '../servisler/ltx/ltx_baglanti_servisi.dart'; class AnaPencere extends ConsumerWidget { final Widget child; const AnaPencere({super.key, required this.child}); static const _yollar = [ '/projeler', '/studyo', '/ai-influencer', '/ace-lora', '/modeller', '/cikis', '/render', '/gecmis', '/ayarlar', ]; @override Widget build(BuildContext context, WidgetRef ref) { final loc = GoRouterState.of(context).uri.path; int idx = 0; for (int i = 0; i < _yollar.length; i++) { if (loc.startsWith(_yollar[i])) idx = i; } final theme = Theme.of(context); final aktifProje = ref.watch(projeProvider); return Scaffold( body: Column( children: [ Expanded( child: Row( children: [ LayoutBuilder( builder: (ctx, kons) => SingleChildScrollView( child: ConstrainedBox( constraints: BoxConstraints(minHeight: kons.maxHeight), child: IntrinsicHeight( child: NavigationRail( extended: false, selectedIndex: idx, onDestinationSelected: (i) => context.go(_yollar[i]), destinations: const [ NavigationRailDestination( icon: Icon(Icons.folder_outlined), selectedIcon: Icon(Icons.folder), label: Text('Projeler'), ), NavigationRailDestination( icon: Icon(Icons.movie_filter_outlined), selectedIcon: Icon(Icons.movie_filter), label: Text('Stüdyo'), ), NavigationRailDestination( icon: Icon(Icons.auto_awesome_outlined), selectedIcon: Icon(Icons.auto_awesome), label: Text('Influencer'), ), NavigationRailDestination( icon: Icon(Icons.music_note_outlined), selectedIcon: Icon(Icons.music_note), label: Text('ACE LoRA'), ), NavigationRailDestination( icon: Icon(Icons.inventory_2_outlined), selectedIcon: Icon(Icons.inventory_2), label: Text('Modeller'), ), NavigationRailDestination( icon: Icon(Icons.tune_outlined), selectedIcon: Icon(Icons.tune), label: Text('Çıkış'), ), NavigationRailDestination( icon: Icon(Icons.play_circle_outline), selectedIcon: Icon(Icons.play_circle), label: Text('Render'), ), NavigationRailDestination( icon: Icon(Icons.history), selectedIcon: Icon(Icons.history_toggle_off), label: Text('Geçmiş'), ), NavigationRailDestination( icon: Icon(Icons.settings_outlined), selectedIcon: Icon(Icons.settings), label: Text('Ayarlar'), ), ], ), ), ), ), ), const VerticalDivider(width: 1), Expanded(child: child), ], ), ), // Mini render bar _MiniRenderBar(aktifProjeIsmi: aktifProje?.isim), _AltDurumBari(aktifProje: aktifProje), ], ), ); } } class _AltDurumBari extends ConsumerWidget { final dynamic aktifProje; const _AltDurumBari({this.aktifProje}); @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); final ltx = ref.watch(ltxBaglantiProvider); return Container( height: 26, color: theme.colorScheme.surface, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ Text( aktifProje != null ? 'Proje: ${aktifProje.isim}' : 'Proje seçilmedi', style: theme.textTheme.labelSmall, ), const Spacer(), GestureDetector( onTap: () => ref.read(ltxBaglantiProvider.notifier).kesfet(), child: Tooltip( message: ltx.baglandi ? 'LTX bağlı: ${ltx.url}' : (ltx.hata ?? 'Bağlantı yok — tıkla yeniden dene'), child: Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 2), decoration: BoxDecoration( color: ltx.baglandi ? Colors.green.withValues(alpha: 0.2) : Colors.red.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(10), border: Border.all( color: ltx.baglandi ? Colors.green : Colors.red, width: 1, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 6, height: 6, decoration: BoxDecoration( shape: BoxShape.circle, color: ltx.baglandi ? Colors.green : Colors.red, ), ), const SizedBox(width: 6), Text( ltx.baglandi ? 'LTX ${ltx.url.replaceAll("http://127.0.0.1:", ":")}' : 'LTX bağlı değil', style: theme.textTheme.labelSmall, ), ], ), ), ), ), const SizedBox(width: 12), Text( 'FikoYT Video Stüdyo · v0.1', style: theme.textTheme.labelSmall, ), ], ), ); } } class _MiniRenderBar extends ConsumerWidget { final String? aktifProjeIsmi; const _MiniRenderBar({this.aktifProjeIsmi}); @override Widget build(BuildContext context, WidgetRef ref) { final joblar = ref.watch(joblarProvider); return joblar.maybeWhen( data: (liste) { final calisan = liste.where((j) => j.durum == JobDurum.calisiyor).toList(); final kuyrukta = liste.where((j) => j.durum == JobDurum.kuyruk).length; if (calisan.isEmpty && kuyrukta == 0) return const SizedBox.shrink(); final theme = Theme.of(context); final j = calisan.isNotEmpty ? calisan.first : null; return Container( height: 36, color: theme.colorScheme.surfaceContainerHighest, padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( children: [ SizedBox( width: 16, height: 16, child: j != null ? CircularProgressIndicator( strokeWidth: 2, value: j.ilerleme / 100, color: theme.colorScheme.primary, ) : const Icon(Icons.queue, size: 16), ), const SizedBox(width: 8), Expanded( child: Text( j != null ? '${j.tip.name} · ${j.ilerleme.toStringAsFixed(0)}% · ${j.fazAciklama}' : 'Kuyrukta $kuyrukta job bekliyor', style: theme.textTheme.labelSmall, overflow: TextOverflow.ellipsis, ), ), if (kuyrukta > 0) ...[ const SizedBox(width: 12), Text('+$kuyrukta', style: theme.textTheme.labelSmall), ], ], ), ); }, orElse: () => const SizedBox.shrink(), ); } }