Solian/lib/screens/account/friend.dart

189 lines
5.5 KiB
Dart
Raw Normal View History

2024-05-23 13:12:47 +00:00
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:get/get.dart';
import 'package:solian/exts.dart';
2024-07-23 17:17:41 +00:00
import 'package:solian/models/relations.dart';
import 'package:solian/providers/relation.dart';
import 'package:solian/widgets/account/relative_list.dart';
2024-05-23 13:12:47 +00:00
class FriendScreen extends StatefulWidget {
const FriendScreen({super.key});
@override
State<FriendScreen> createState() => _FriendScreenState();
}
2024-07-23 17:17:41 +00:00
class _FriendScreenState extends State<FriendScreen>
with SingleTickerProviderStateMixin {
late final TabController _tabController;
2024-05-23 13:12:47 +00:00
bool _isBusy = false;
2024-07-23 17:17:41 +00:00
List<Relationship> _relations = List.empty();
2024-05-23 13:12:47 +00:00
2024-07-23 17:17:41 +00:00
List<Relationship> filterByStatus(int status) {
return _relations.where((x) => x.status == status).toList();
2024-05-23 13:12:47 +00:00
}
2024-07-23 17:17:41 +00:00
Future<void> loadRelations() async {
2024-05-23 13:12:47 +00:00
setState(() => _isBusy = true);
2024-07-23 17:17:41 +00:00
final RelationshipProvider provider = Get.find();
final resp = await provider.listRelation();
2024-05-23 13:12:47 +00:00
setState(() {
2024-07-23 17:17:41 +00:00
_relations = resp.body
.map((e) => Relationship.fromJson(e))
2024-05-23 13:12:47 +00:00
.toList()
2024-07-23 17:17:41 +00:00
.cast<Relationship>();
2024-05-23 13:12:47 +00:00
_isBusy = false;
});
}
void promptAddFriend() async {
2024-07-23 17:17:41 +00:00
final RelationshipProvider provider = Get.find();
2024-05-23 13:12:47 +00:00
final controller = TextEditingController();
2024-07-23 17:17:41 +00:00
final input = await showDialog<String?>(
2024-05-23 13:12:47 +00:00
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: <Widget>[
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);
2024-07-23 17:17:41 +00:00
await provider.makeFriend(input);
2024-05-23 13:12:47 +00:00
} catch (e) {
context.showErrorDialog(e);
} finally {
setState(() => _isBusy = false);
}
}
@override
void initState() {
super.initState();
2024-07-23 17:17:41 +00:00
_tabController = TabController(length: 3, vsync: this);
2024-05-23 13:12:47 +00:00
2024-07-23 17:17:41 +00:00
loadRelations().then((_) {
if (filterByStatus(0).isEmpty) {
_tabController.animateTo(1);
}
});
2024-05-23 13:12:47 +00:00
}
@override
Widget build(BuildContext context) {
return Material(
color: Theme.of(context).colorScheme.surface,
child: Scaffold(
2024-07-23 17:17:41 +00:00
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)),
],
),
),
2024-05-23 13:12:47 +00:00
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () => promptAddFriend(),
),
2024-07-23 17:17:41 +00:00
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(),
2024-05-23 13:12:47 +00:00
),
2024-07-23 17:17:41 +00:00
],
2024-05-23 13:12:47 +00:00
),
2024-07-23 17:17:41 +00:00
),
RefreshIndicator(
onRefresh: () => loadRelations(),
child: CustomScrollView(
slivers: [
if (_isBusy)
SliverToBoxAdapter(
child: const LinearProgressIndicator().animate().scaleX(),
),
SilverRelativeList(
items: filterByStatus(1),
onUpdate: () => loadRelations(),
2024-05-23 13:12:47 +00:00
),
2024-07-23 17:17:41 +00:00
],
2024-05-23 13:12:47 +00:00
),
2024-07-23 17:17:41 +00:00
),
RefreshIndicator(
onRefresh: () => loadRelations(),
child: CustomScrollView(
slivers: [
if (_isBusy)
SliverToBoxAdapter(
child: const LinearProgressIndicator().animate().scaleX(),
),
SilverRelativeList(
items: filterByStatus(3),
onUpdate: () => loadRelations(),
),
],
2024-05-23 13:12:47 +00:00
),
2024-07-23 17:17:41 +00:00
),
],
2024-05-23 13:12:47 +00:00
),
),
);
}
}