Encrypted messaging app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.6 KiB

  1. import 'package:flutter/material.dart';
  2. import '/components/custom_title_bar.dart';
  3. import '/components/qr_reader.dart';
  4. import '/components/custom_expandable_fab.dart';
  5. import '/database/models/friends.dart';
  6. import '/views/main/friend/list_item.dart';
  7. import '/views/main/friend/add_search.dart';
  8. import '/views/main/friend/request_list_item.dart';
  9. class FriendList extends StatefulWidget {
  10. final List<Friend> friends;
  11. final List<Friend> friendRequests;
  12. final Function callback;
  13. const FriendList({
  14. Key? key,
  15. required this.friends,
  16. required this.friendRequests,
  17. required this.callback,
  18. }) : super(key: key);
  19. @override
  20. State<FriendList> createState() => _FriendListState();
  21. }
  22. class _FriendListState extends State<FriendList> {
  23. List<Friend> friends = [];
  24. List<Friend> friendRequests = [];
  25. List<Friend> friendsDuplicate = [];
  26. List<Friend> friendRequestsDuplicate = [];
  27. @override
  28. Widget build(BuildContext context) {
  29. return Scaffold(
  30. appBar: const CustomTitleBar(
  31. title: Text(
  32. 'Friends',
  33. style: TextStyle(
  34. fontSize: 32,
  35. fontWeight: FontWeight.bold
  36. )
  37. ),
  38. showBack: false,
  39. backgroundColor: Colors.transparent,
  40. ),
  41. body: Padding(
  42. padding: const EdgeInsets.only(top: 16,left: 16,right: 16),
  43. child: SingleChildScrollView(
  44. child: Column(
  45. children: <Widget>[
  46. TextField(
  47. decoration: const InputDecoration(
  48. hintText: 'Search...',
  49. prefixIcon: Icon(
  50. Icons.search,
  51. size: 20
  52. ),
  53. ),
  54. onChanged: (value) => filterSearchResults(value.toLowerCase())
  55. ),
  56. headingOrNull('Friend Requests'),
  57. friendRequestList(),
  58. headingOrNull('Friends'),
  59. friendList(),
  60. ],
  61. ),
  62. ),
  63. ),
  64. floatingActionButton: Padding(
  65. padding: const EdgeInsets.only(right: 10, bottom: 10),
  66. child: ExpandableFab(
  67. icon: Icon(
  68. Icons.add,
  69. size: 30,
  70. color: Theme.of(context).colorScheme.onPrimary,
  71. ),
  72. distance: 90.0,
  73. children: [
  74. ActionButton(
  75. onPressed: () {
  76. Navigator.of(context).push(
  77. MaterialPageRoute(builder: (context) => const QrReader())
  78. );//.then(onGoBack); // TODO
  79. },
  80. icon: const Icon(Icons.qr_code_2, size: 25),
  81. ),
  82. ActionButton(
  83. onPressed: () {
  84. Navigator.of(context).push(
  85. MaterialPageRoute(builder: (context) => const FriendAddSearch())
  86. );//.then(onGoBack); // TODO
  87. },
  88. icon: const Icon(Icons.search, size: 25),
  89. ),
  90. ],
  91. )
  92. )
  93. );
  94. }
  95. void filterSearchResults(String query) {
  96. List<Friend> dummyFriendsList = [];
  97. List<Friend> dummyFriendRequestsList = [];
  98. dummyFriendsList.addAll(friends);
  99. dummyFriendRequestsList.addAll(friendRequests);
  100. if (query.isNotEmpty) {
  101. List<Friend> dummyFriendData = [];
  102. List<Friend> dummyFriendRequestData = [];
  103. for (Friend item in dummyFriendsList) {
  104. if(item.username.toLowerCase().contains(query)) {
  105. dummyFriendData.add(item);
  106. }
  107. }
  108. for (Friend item in dummyFriendRequestsList) {
  109. if(item.username.toLowerCase().contains(query)) {
  110. dummyFriendRequestData.add(item);
  111. }
  112. }
  113. setState(() {
  114. friends.clear();
  115. friends.addAll(dummyFriendData);
  116. friendRequests.clear();
  117. friendRequests.addAll(dummyFriendRequestData);
  118. });
  119. return;
  120. }
  121. setState(() {
  122. friends.clear();
  123. friends.addAll(widget.friends);
  124. friendRequests.clear();
  125. friendRequests.addAll(widget.friendRequests);
  126. });
  127. }
  128. @override
  129. void initState() {
  130. super.initState();
  131. friends.addAll(widget.friends);
  132. friendRequests.addAll(widget.friendRequests);
  133. }
  134. Future<void> initFriends() async {
  135. friends = await getFriends(accepted: true);
  136. friendRequests = await getFriends(accepted: false);
  137. setState(() {});
  138. widget.callback();
  139. }
  140. Widget headingOrNull(String heading) {
  141. if (friends.isEmpty || friendRequests.isEmpty) {
  142. return const SizedBox.shrink();
  143. }
  144. return Padding(
  145. padding: const EdgeInsets.only(top: 16),
  146. child: Align(
  147. alignment: Alignment.centerLeft,
  148. child: Text(
  149. heading,
  150. style: TextStyle(
  151. fontSize: 16,
  152. color: Theme.of(context).hintColor,
  153. ),
  154. ),
  155. )
  156. );
  157. }
  158. Widget friendRequestList() {
  159. if (friendRequests.isEmpty) {
  160. return const SizedBox.shrink();
  161. }
  162. return ListView.builder(
  163. itemCount: friendRequests.length,
  164. shrinkWrap: true,
  165. padding: const EdgeInsets.only(top: 16),
  166. physics: const NeverScrollableScrollPhysics(),
  167. itemBuilder: (context, i) {
  168. return FriendRequestListItem(
  169. friend: friendRequests[i],
  170. callback: initFriends,
  171. );
  172. },
  173. );
  174. }
  175. Widget friendList() {
  176. if (friends.isEmpty) {
  177. return const Center(
  178. child: Text('No Friends'),
  179. );
  180. }
  181. return ListView.builder(
  182. itemCount: friends.length,
  183. shrinkWrap: true,
  184. padding: const EdgeInsets.only(top: 16),
  185. physics: const NeverScrollableScrollPhysics(),
  186. itemBuilder: (context, i) {
  187. return FriendListItem(
  188. friend: friends[i],
  189. );
  190. },
  191. );
  192. }
  193. }