import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/network/api_exception.dart'; import '../../core/theme/theme_x.dart'; import '../../data/repositories/node_repository.dart'; import 'widgets/connection_form_dialog.dart'; import 'widgets/connections_list.dart'; import 'widgets/no_auth_callout.dart'; import 'widgets/node_identity_form.dart'; import 'widgets/theme_toggle.dart'; class SettingsScreen extends ConsumerWidget { const SettingsScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { return ListView( padding: const EdgeInsets.all(24), children: [ _Block( title: 'Connections', trailing: TextButton.icon( onPressed: () => showConnectionFormDialog(context), icon: const Icon(Icons.add, size: 17), label: const Text('Add connection'), ), child: const ConnectionsList(), ), const SizedBox(height: 22), _Block(title: 'Node identity', child: const _NodeIdentitySection()), const SizedBox(height: 22), _Block( title: 'Appearance', child: const Padding( padding: EdgeInsets.all(16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Theme'), ThemeToggle(), ], ), ), ), const SizedBox(height: 22), const NoAuthCallout(), ], ); } } class _NodeIdentitySection extends ConsumerWidget { const _NodeIdentitySection(); @override Widget build(BuildContext context, WidgetRef ref) { final nodeAsync = ref.watch(currentNodeProvider); return nodeAsync.when( loading: () => const Padding( padding: EdgeInsets.all(16), child: Row( children: [ SizedBox(width: 14, height: 14, child: CircularProgressIndicator(strokeWidth: 2)), SizedBox(width: 10), Text('Contacting node…'), ], ), ), error: (error, stackTrace) { final message = error is ApiException ? error.userMessage : error.toString(); return Padding( padding: const EdgeInsets.all(16), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon(Icons.error_outline, size: 18, color: context.status.critical), const SizedBox(width: 10), Expanded( child: Text(message, style: context.text.bodyMedium?.copyWith(color: context.status.critical)), ), ], ), ); }, data: (node) { if (node == null) { return const Padding( padding: EdgeInsets.all(16), child: Text('No connection selected.'), ); } return NodeIdentityForm(node: node); }, ); } } class _Block extends StatelessWidget { const _Block({required this.title, required this.child, this.trailing}); final String title; final Widget child; final Widget? trailing; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: context.text.titleMedium), trailing ?? const SizedBox.shrink(), ], ), const SizedBox(height: 10), Card(child: child), ], ); } }