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.

216 lines
5.7 KiB

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