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.

204 lines
5.2 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 Function callback;
  13. const FriendList({
  14. Key? key,
  15. required this.friends,
  16. required this.callback,
  17. }) : super(key: key);
  18. @override
  19. State<FriendList> createState() => _FriendListState();
  20. }
  21. class _FriendListState extends State<FriendList> {
  22. final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey = GlobalKey<RefreshIndicatorState>();
  23. List<Friend> friends = [];
  24. List<Friend> friendsDuplicate = [];
  25. @override
  26. Widget build(BuildContext context) {
  27. return Scaffold(
  28. appBar: const CustomTitleBar(
  29. title: Text(
  30. 'Friends',
  31. style: TextStyle(
  32. fontSize: 32,
  33. fontWeight: FontWeight.bold
  34. )
  35. ),
  36. showBack: false,
  37. backgroundColor: Colors.transparent,
  38. ),
  39. body: Padding(
  40. padding: const EdgeInsets.only(top: 16,left: 16,right: 16, bottom: 65),
  41. child: Stack(
  42. children: <Widget>[
  43. Padding(
  44. padding: const EdgeInsets.only(top: 50),
  45. child: RefreshIndicator(
  46. key: _refreshIndicatorKey,
  47. onRefresh: _refresh,
  48. child: list(),
  49. )
  50. ),
  51. TextField(
  52. decoration: const InputDecoration(
  53. hintText: 'Search...',
  54. prefixIcon: Icon(
  55. Icons.search,
  56. size: 20
  57. ),
  58. ),
  59. onChanged: (value) => filterSearchResults(value.toLowerCase())
  60. ),
  61. ],
  62. ),
  63. ),
  64. floatingActionButton: Padding(
  65. padding: const EdgeInsets.only(right: 10, bottom: 60),
  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. dummyFriendsList.addAll(friends);
  98. if (query.isNotEmpty) {
  99. List<Friend> dummyFriendData = [];
  100. for (Friend item in dummyFriendsList) {
  101. if(item.username.toLowerCase().contains(query)) {
  102. dummyFriendData.add(item);
  103. }
  104. }
  105. setState(() {
  106. friends.clear();
  107. friends.addAll(dummyFriendData);
  108. });
  109. return;
  110. }
  111. setState(() {
  112. friends.clear();
  113. friends.addAll(widget.friends);
  114. });
  115. }
  116. @override
  117. void initState() {
  118. super.initState();
  119. friends.addAll(widget.friends);
  120. }
  121. Future<void> initFriends() async {
  122. friends = await FriendsRepository.getFriends();
  123. setState(() {});
  124. widget.callback();
  125. }
  126. Widget _heading(String heading) {
  127. return Padding(
  128. padding: const EdgeInsets.only(top: 5, bottom: 10),
  129. child: Align(
  130. alignment: Alignment.centerLeft,
  131. child: Text(
  132. heading,
  133. style: TextStyle(
  134. fontSize: 16,
  135. color: Theme.of(context).hintColor,
  136. ),
  137. ),
  138. )
  139. );
  140. }
  141. Widget list() {
  142. if (friends.isEmpty) {
  143. return const Center(
  144. child: Text('No Friends'),
  145. );
  146. }
  147. return ListView.separated(
  148. itemCount: friends.length,
  149. shrinkWrap: false,
  150. physics: const AlwaysScrollableScrollPhysics(),
  151. padding: const EdgeInsets.only(top: 10),
  152. separatorBuilder: (context, i) {
  153. if (friends[i].acceptedAt == null) {
  154. return FriendRequestListItem(
  155. friend: friends[i],
  156. callback: initFriends,
  157. );
  158. }
  159. return FriendListItem(
  160. friend: friends[i],
  161. );
  162. },
  163. itemBuilder: (context, i) {
  164. if (i == 0 && friends[i].acceptedAt == null) {
  165. return _heading('Friend Requests');
  166. }
  167. if ((i == 0 || friends[i - 1].acceptedAt == null) && friends[i].acceptedAt != null) {
  168. return _heading('Friends');
  169. }
  170. return const SizedBox.shrink();
  171. },
  172. );
  173. }
  174. Future<void> _refresh() async {
  175. Future.delayed(
  176. const Duration(seconds: 1),
  177. () {
  178. print('Doing thing');
  179. }
  180. );
  181. }
  182. }