import 'package:flutter/cupertino.dart'; import 'package:macos_ui/macos_ui.dart'; import '../../rust/api/packages.dart'; import '../../rust/frb_generated.dart'; class InstalledScreen extends StatefulWidget { final Function(String name, BackendType backend)? onInspectPackage; const InstalledScreen({ super.key, this.onInspectPackage, }); @override State createState() => _InstalledScreenState(); } class _InstalledScreenState extends State { List _packages = []; String _searchQuery = ''; bool _isLoading = true; BackendType? _filterBackend; @override void initState() { super.initState(); _loadInstalled(); } Future _loadInstalled() async { setState(() => _isLoading = true); try { final list = await RustBridgeApi.getInstalledPackages(backend: _filterBackend); if (mounted) { setState(() { _packages = list; _isLoading = false; }); } } catch (e) { if (mounted) setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { final filtered = _packages.where((p) { return p.name.toLowerCase().contains(_searchQuery.toLowerCase()) || p.description.toLowerCase().contains(_searchQuery.toLowerCase()); }).toList(); return MacosScaffold( toolBar: ToolBar( title: const Text('Установленные пакеты'), leading: MacosTooltip( message: 'Боковая панель', child: MacosIconButton( icon: const MacosIcon(CupertinoIcons.sidebar_left), onPressed: () => MacosWindowScope.of(context).toggleSidebar(), ), ), actions: [ // Filter Popup CustomToolbarItem( inToolbarBuilder: (context) => Padding( padding: const EdgeInsets.only(right: 8.0), child: MacosPopupButton( value: _filterBackend, items: const [ MacosPopupMenuItem(value: null, child: Text('Все бэкенды')), MacosPopupMenuItem( value: BackendType.pacman, child: Text('Pacman')), MacosPopupMenuItem( value: BackendType.flatpak, child: Text('Flatpak')), ], onChanged: (b) { setState(() => _filterBackend = b); _loadInstalled(); }, ), ), ), CustomToolbarItem( inToolbarBuilder: (context) => Padding( padding: const EdgeInsets.only(right: 8.0), child: SizedBox( width: 220, child: MacosTextField( placeholder: 'Поиск пакета...', placeholderStyle: const TextStyle( color: CupertinoColors.systemGrey2, fontSize: 13, ), prefix: const Padding( padding: EdgeInsets.symmetric(horizontal: 6), child: MacosIcon( CupertinoIcons.search, size: 14, color: CupertinoColors.systemGrey, ), ), onChanged: (val) => setState(() => _searchQuery = val), ), ), ), ), ], ), children: [ ContentArea( builder: (context, scrollController) { if (_isLoading) { return const Center(child: ProgressCircle(radius: 16)); } return ListView.separated( controller: scrollController, padding: const EdgeInsets.symmetric(horizontal: 28, vertical: 20), itemCount: filtered.length, separatorBuilder: (_, _) => const SizedBox(height: 8), itemBuilder: (context, idx) { final pkg = filtered[idx]; final isFlatpak = pkg.backend == BackendType.flatpak; return Container( decoration: BoxDecoration( color: const Color(0xFF222224), borderRadius: BorderRadius.circular(8), border: Border.all( color: CupertinoColors.white.withValues(alpha: 0.08), width: 0.8, ), ), child: CupertinoButton( padding: const EdgeInsets.symmetric( horizontal: 14, vertical: 12), alignment: Alignment.centerLeft, pressedOpacity: 0.7, onPressed: () { widget.onInspectPackage?.call(pkg.name, pkg.backend); }, child: Row( children: [ MacosIcon( isFlatpak ? CupertinoIcons.app_badge_fill : CupertinoIcons.cube_box_fill, size: 20, color: isFlatpak ? const Color(0xFF4A90E2) : const Color(0xFF1793D1), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( pkg.name, style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 14, color: CupertinoColors.white, ), ), const SizedBox(width: 8), Text( pkg.version, style: const TextStyle( fontFamily: 'monospace', color: CupertinoColors.systemGrey, fontSize: 12, ), ), const Spacer(), Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2), decoration: BoxDecoration( color: isFlatpak ? const Color(0xFF4A90E2) .withValues(alpha: 0.12) : const Color(0xFF1793D1) .withValues(alpha: 0.12), borderRadius: BorderRadius.circular(4), ), child: Text( pkg.backend.displayName, style: TextStyle( fontSize: 10.5, fontWeight: FontWeight.bold, color: isFlatpak ? const Color(0xFF4A90E2) : const Color(0xFF1793D1), ), ), ), ], ), const SizedBox(height: 3), Text( pkg.description, style: const TextStyle( fontSize: 12, color: CupertinoColors.systemGrey, ), ), ], ), ), const SizedBox(width: 14), Text( pkg.formattedSize, style: const TextStyle( fontSize: 11.5, color: CupertinoColors.systemGrey, ), ), const SizedBox(width: 8), const MacosIcon( CupertinoIcons.chevron_right, size: 13, color: CupertinoColors.systemGrey, ), ], ), ), ); }, ); }, ), ], ); } }