import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:get/get.dart'; import 'package:solian/exts.dart'; import 'package:solian/models/relations.dart'; import 'package:solian/providers/relation.dart'; import 'package:solian/widgets/account/relative_list.dart'; class FriendScreen extends StatefulWidget { const FriendScreen({super.key}); @override State createState() => _FriendScreenState(); } class _FriendScreenState extends State with SingleTickerProviderStateMixin { late final TabController _tabController; bool _isBusy = false; List _relations = List.empty(); List filterByStatus(int status) { return _relations.where((x) => x.status == status).toList(); } Future loadRelations() async { setState(() => _isBusy = true); final RelationshipProvider provider = Get.find(); final resp = await provider.listRelation(); setState(() { _relations = resp.body .map((e) => Relationship.fromJson(e)) .toList() .cast(); _isBusy = false; }); } void promptAddFriend() async { final RelationshipProvider provider = Get.find(); final controller = TextEditingController(); final input = await showDialog( context: context, builder: (context) { return AlertDialog( title: Text('accountFriendNew'.tr), content: Column( mainAxisSize: MainAxisSize.min, children: [ Text('accountFriendNewHint'.tr, textAlign: TextAlign.left), const SizedBox(height: 18), TextField( controller: controller, decoration: InputDecoration( border: const OutlineInputBorder(), labelText: 'username'.tr, ), onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), ), ], ), actions: [ TextButton( style: TextButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.onSurface.withOpacity(0.8), ), onPressed: () => Navigator.pop(context), child: Text('cancel'.tr), ), TextButton( child: Text('next'.tr), onPressed: () { Navigator.pop(context, controller.text); }, ), ], ); }, ); WidgetsBinding.instance.addPostFrameCallback((_) => controller.dispose()); if (input == null || input.isEmpty) return; try { setState(() => _isBusy = true); await provider.makeFriend(input); } catch (e) { context.showErrorDialog(e); } finally { setState(() => _isBusy = false); } } @override void initState() { super.initState(); _tabController = TabController(length: 3, vsync: this); loadRelations().then((_) { if (filterByStatus(0).isEmpty) { _tabController.animateTo(1); } }); } @override Widget build(BuildContext context) { return Material( color: Theme.of(context).colorScheme.surface, child: Scaffold( appBar: AppBar( centerTitle: false, title: Text('accountFriend'.tr), bottom: TabBar( controller: _tabController, tabs: const [ Tab(icon: Icon(Icons.call_received)), Tab(icon: Icon(Icons.people)), Tab(icon: Icon(Icons.call_made)), ], ), ), floatingActionButton: FloatingActionButton( child: const Icon(Icons.add), onPressed: () => promptAddFriend(), ), body: TabBarView( controller: _tabController, children: [ RefreshIndicator( onRefresh: () => loadRelations(), child: CustomScrollView( slivers: [ if (_isBusy) SliverToBoxAdapter( child: const LinearProgressIndicator().animate().scaleX(), ), SilverRelativeList( items: filterByStatus(0), onUpdate: () => loadRelations(), ), ], ), ), RefreshIndicator( onRefresh: () => loadRelations(), child: CustomScrollView( slivers: [ if (_isBusy) SliverToBoxAdapter( child: const LinearProgressIndicator().animate().scaleX(), ), SilverRelativeList( items: filterByStatus(1), onUpdate: () => loadRelations(), ), ], ), ), RefreshIndicator( onRefresh: () => loadRelations(), child: CustomScrollView( slivers: [ if (_isBusy) SliverToBoxAdapter( child: const LinearProgressIndicator().animate().scaleX(), ), SilverRelativeList( items: filterByStatus(3), onUpdate: () => loadRelations(), ), ], ), ), ], ), ), ); } }