together_mobile/lib/screens/contact/contact_screen.dart

286 lines
9.3 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:badges/badges.dart' as badges;
import 'package:together_mobile/common/constants.dart';
import 'package:together_mobile/models/apply_list_model.dart';
import 'package:together_mobile/models/init_get_it.dart';
import 'package:together_mobile/models/user_model.dart';
import 'package:together_mobile/screens/contact/components/friend_tile.dart';
import 'package:together_mobile/screens/contact/components/group_chat_tile.dart';
class ContactScreen extends StatefulWidget {
const ContactScreen({super.key});
@override
State<ContactScreen> createState() => _ContactScreenState();
}
class _ContactScreenState extends State<ContactScreen> {
final Map<String, bool> _shows = {
'friendGroups': true,
'allFriends': false,
'groupChats': false
};
@override
Widget build(BuildContext context) {
// Create a localkey, use to generate the custom scroll view,
// or there will be a error: "Duplicate GlobalKey detected in widget tree."
// But when I wrap custom scroll view into the RefrashIndicator, the key isn't needed any more
// const Key customScrollKey = ValueKey<String>('bottom-sliver-list');
return Scaffold(
appBar: AppBar(
leading: Container(
margin: const EdgeInsets.only(left: 8),
child: getIt.get<UserProfile>().avatar.isEmpty
? const CircleAvatar(
backgroundImage: AssetImage('assets/images/user_2.png'),
)
: CircleAvatar(
backgroundImage: FileImage(
File(getIt.get<UserProfile>().avatar),
),
),
),
title: const Text('通讯录'),
centerTitle: true,
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.search),
splashRadius: 20,
),
IconButton(
onPressed: () {
context.push('/contact/add');
},
icon: const Icon(Icons.person_add_alt_1),
splashRadius: 20,
),
],
),
body: RefreshIndicator(
onRefresh: () async {
await Future.delayed(const Duration(seconds: 2));
},
child: CustomScrollView(
physics: const BouncingScrollPhysics(),
// key: customScrollKey,
slivers: [
SliverFixedExtentList(
delegate: SliverChildListDelegate(
[
TextButton(
onPressed: () async {
// await getApplicantInfo(getIt.get<ApplyList>().applicantIds);
context.push('/contact/apply_list');
},
style: TextButton.styleFrom(
iconColor: Theme.of(context).textTheme.bodyLarge?.color,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
badges.Badge(
badgeStyle: const badges.BadgeStyle(
badgeColor: kErrorColor,
elevation: 12,
),
badgeContent: Text(
getIt.get<ApplyList>().count.toString(),
style: TextStyle(
fontSize: 11,
color:
Theme.of(context).colorScheme.inversePrimary,
),
),
badgeAnimation: const badges.BadgeAnimation.scale(),
position:
badges.BadgePosition.topEnd(top: -12, end: -15),
child: Text(
'添加申请',
style: TextStyle(
fontSize: 16,
color:
Theme.of(context).textTheme.bodyLarge?.color,
),
),
),
const Icon(
Icons.keyboard_arrow_right,
size: 30,
),
],
),
),
TextButton(
onPressed: () {
context.push('/contact/friend_group');
},
style: TextButton.styleFrom(
iconColor: Theme.of(context).textTheme.bodyLarge?.color,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'分组管理',
style: TextStyle(
fontSize: 16,
color: Theme.of(context).textTheme.bodyLarge?.color,
),
),
const Icon(
Icons.keyboard_arrow_right,
size: 30,
),
],
),
),
],
),
itemExtent: 50.0,
),
SliverPersistentHeader(
delegate: _MySliverPersistentHeader(_shows, _change, _refresh),
pinned: true,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return const FriendTile();
},
childCount: 15,
),
),
],
),
),
);
}
void _change(String which) {
switch (which) {
case 'friendGroups':
setState(() {
_shows['friendGroups'] = true;
_shows['allFriends'] = false;
_shows['groupChats'] = false;
});
break;
case 'allFriends':
setState(() {
_shows['friendGroups'] = false;
_shows['allFriends'] = true;
_shows['groupChats'] = false;
});
break;
case 'groupChats':
setState(() {
_shows['friendGroups'] = false;
_shows['allFriends'] = false;
_shows['groupChats'] = true;
});
break;
}
}
void _refresh() {
setState(() {});
}
}
class _MySliverPersistentHeader extends SliverPersistentHeaderDelegate {
const _MySliverPersistentHeader(this.shows, this.change, this.refresh);
final Map<String, bool> shows;
final Function(String) change;
final VoidCallback refresh;
@override
double get minExtent => 50;
@override
double get maxExtent => 50;
@override
Widget build(
BuildContext context,
double shrinkOffset,
bool overlapsContent,
) {
return Container(
height: 50,
color: Theme.of(context).colorScheme.background,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () {
change('friendGroups');
refresh();
},
child: Container(
margin: const EdgeInsets.only(left: 10),
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: shows['friendGroups']!
? kSecondaryColor.withOpacity(0.15)
: Theme.of(context).brightness == Brightness.light
? null
: Theme.of(context).colorScheme.background,
),
child: const Text('分组'),
),
),
InkWell(
onTap: () {
change('allFriends');
},
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: shows['allFriends']!
? kSecondaryColor.withOpacity(0.15)
: Theme.of(context).brightness == Brightness.light
? null
: Theme.of(context).colorScheme.background,
),
child: const Text('全部好友'),
),
),
InkWell(
onTap: () {
change('groupChats');
},
child: Container(
margin: const EdgeInsets.only(right: 10),
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: shows['groupChats']!
? kSecondaryColor.withOpacity(0.15)
: Theme.of(context).brightness == Brightness.light
? null
: Theme.of(context).colorScheme.background,
),
child: const Text('群聊'),
),
),
],
),
);
}
@override
bool shouldRebuild(covariant _MySliverPersistentHeader oldDelegate) {
return false;
}
}