/// Sidebar panel showing project diagnostics from pql. library; import 'dart:async'; import 'package:clide/kernel/kernel.dart'; import 'package:clide/widgets/widgets.dart'; import 'package:flutter/widgets.dart'; import 'problems_controller.dart'; class ProblemsView extends StatefulWidget { const ProblemsView({super.key}); @override State createState() => _ProblemsViewState(); } class _ProblemsViewState extends State { ProblemsController? _controller; @override void didChangeDependencies() { super.didChangeDependencies(); if (_controller != null) return; final kernel = ClideKernel.of(context); _controller = ProblemsController(ipc: kernel.ipc); unawaited(_controller!.refresh()); } @override void dispose() { _controller?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final c = _controller; if (c == null) return const SizedBox.shrink(); return ListenableBuilder( listenable: c, builder: (context, _) { final tokens = ClideTheme.of(context).surface; return Semantics( label: 'problems panel', container: true, explicitChildNodes: true, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Padding( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6), child: Row( children: [ Expanded( child: ClideText( 'Problems (${c.problems.length})', fontSize: clideFontCaption, color: tokens.sidebarForeground, ), ), Semantics( button: true, label: 'refresh problems', child: GestureDetector( onTap: () => unawaited(c.refresh()), child: MouseRegion( cursor: SystemMouseCursors.click, child: ClideText( 'Refresh', fontSize: clideFontCaption, color: tokens.sidebarForeground, ), ), ), ), ], ), ), if (c.loading && c.problems.isEmpty) const Padding( padding: EdgeInsets.all(12), child: ClideText('Scanning…', muted: true), ), if (!c.loading && c.problems.isEmpty) const Padding( padding: EdgeInsets.all(12), child: ClideText( 'No problems found.', muted: true, ), ), Expanded( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 4), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ for (final p in c.problems) _ProblemRow(problem: p), ], ), ), ), ], ), ); }, ); } } class _ProblemRow extends StatelessWidget { const _ProblemRow({required this.problem}); final Problem problem; @override Widget build(BuildContext context) { final tokens = ClideTheme.of(context).surface; return Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Row( children: [ ClideText( problem.source, fontSize: clideFontMono, color: tokens.statusWarning, fontFamily: clideMonoFamily, ), const SizedBox(width: 6), Expanded( child: ClideText( problem.message, color: tokens.sidebarForeground, maxLines: 2, ), ), ], ), if (problem.hint != null) Padding( padding: const EdgeInsets.only(left: 44, top: 2), child: ClideText( problem.hint!, fontSize: clideFontMono, muted: true, fontFamily: clideMonoFamily, ), ), ], ), ); } }