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.

214 lines
6.1 KiB

  1. import 'package:flutter/material.dart';
  2. import 'package:http/http.dart' as http;
  3. import '/database/models/conversations.dart';
  4. import '/database/models/friends.dart';
  5. import '/database/models/my_profile.dart';
  6. import '/database/repositories/conversations_repository.dart';
  7. import '/database/repositories/friends_repository.dart';
  8. import '/services/conversations_service.dart';
  9. import '/services/friends_service.dart';
  10. import '/services/messages_service.dart';
  11. import '/utils/storage/session_cookie.dart';
  12. import '/views/main/conversation/list.dart';
  13. import '/views/main/friend/list.dart';
  14. import '/views/main/profile/profile.dart';
  15. class Home extends StatefulWidget {
  16. const Home({Key? key}) : super(key: key);
  17. @override
  18. State<Home> createState() => _HomeState();
  19. }
  20. class _HomeState extends State<Home> {
  21. List<Conversation> conversations = [];
  22. List<Friend> friends = [];
  23. List<Friend> friendRequests = [];
  24. MyProfile profile = MyProfile(
  25. id: '',
  26. username: '',
  27. messageExpiryDefault: 'no_expiry',
  28. );
  29. bool isLoading = true;
  30. int _selectedIndex = 0;
  31. List<Widget> _widgetOptions = <Widget>[
  32. const ConversationList(conversations: [], friends: []),
  33. FriendList(friends: const [], friendRequests: const [], callback: () {}),
  34. Profile(
  35. profile: MyProfile(
  36. id: '',
  37. username: '',
  38. messageExpiryDefault: 'no_expiry',
  39. )
  40. ),
  41. ];
  42. @override
  43. Widget build(BuildContext context) {
  44. return WillPopScope(
  45. onWillPop: () async => false,
  46. child: isLoading ? loading() : Scaffold(
  47. body: _widgetOptions.elementAt(_selectedIndex),
  48. bottomNavigationBar: isLoading ?
  49. const SizedBox.shrink() :
  50. BottomNavigationBar(
  51. currentIndex: _selectedIndex,
  52. onTap: _onItemTapped,
  53. selectedItemColor: Theme.of(context).primaryColor,
  54. unselectedItemColor: Theme.of(context).hintColor,
  55. selectedLabelStyle: const TextStyle(fontWeight: FontWeight.w600),
  56. unselectedLabelStyle: const TextStyle(fontWeight: FontWeight.w600),
  57. backgroundColor: Colors.transparent,
  58. elevation: 0,
  59. type: BottomNavigationBarType.fixed,
  60. items: const [
  61. BottomNavigationBarItem(
  62. icon: Icon(Icons.message),
  63. label: 'Chats',
  64. ),
  65. BottomNavigationBarItem(
  66. icon: Icon(Icons.group_work),
  67. label: 'Friends',
  68. ),
  69. BottomNavigationBarItem(
  70. icon: Icon(Icons.account_box),
  71. label: 'Profile',
  72. ),
  73. ],
  74. ),
  75. ),
  76. );
  77. }
  78. Future<bool> checkLogin() async {
  79. bool isLoggedIn = false;
  80. try {
  81. isLoggedIn = await MyProfile.isLoggedIn();
  82. } catch (Exception) {
  83. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  84. return false;
  85. }
  86. if (!isLoggedIn) {
  87. await MyProfile.logout();
  88. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  89. return false;
  90. }
  91. int statusCode = 200;
  92. try {
  93. var resp = await http.get(
  94. await MyProfile.getServerUrl('api/v1/auth/check'),
  95. headers: {
  96. 'cookie': await getSessionCookie(),
  97. }
  98. );
  99. statusCode = resp.statusCode;
  100. } catch(SocketException) {
  101. if (await MyProfile.isLoggedIn()) {
  102. return true;
  103. }
  104. }
  105. if (isLoggedIn && statusCode == 200) {
  106. return true;
  107. }
  108. MyProfile.logout();
  109. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  110. return false;
  111. }
  112. @override
  113. void initState() {
  114. super.initState();
  115. updateData();
  116. }
  117. Widget loading() {
  118. return Stack(
  119. children: <Widget>[
  120. const Opacity(
  121. opacity: 0.1,
  122. child: ModalBarrier(dismissible: false, color: Colors.black),
  123. ),
  124. Center(
  125. child: Column(
  126. mainAxisSize: MainAxisSize.max,
  127. mainAxisAlignment: MainAxisAlignment.center,
  128. children: const <Widget> [
  129. CircularProgressIndicator(),
  130. SizedBox(height: 25),
  131. Text('Loading...'),
  132. ],
  133. )
  134. ),
  135. ]
  136. );
  137. }
  138. void updateData() async {
  139. if (!await checkLogin()) {
  140. return;
  141. }
  142. await FriendsService.updateFriends();
  143. await ConversationsService.updateConversations();
  144. await MessagesService.updateMessageThreads();
  145. conversations = await ConversationsRepository.getConversations();
  146. friends = await FriendsRepository.getFriends(accepted: true);
  147. friendRequests = await FriendsRepository.getFriends(accepted: false);
  148. profile = await MyProfile.getProfile();
  149. setState(() {
  150. _widgetOptions = <Widget>[
  151. ConversationList(
  152. conversations: conversations,
  153. friends: friends,
  154. ),
  155. FriendList(
  156. friends: friends,
  157. friendRequests: friendRequests,
  158. callback: reinitDatabaseRecords,
  159. ),
  160. Profile(profile: profile),
  161. ];
  162. isLoading = false;
  163. });
  164. }
  165. Future<void> reinitDatabaseRecords() async {
  166. conversations = await ConversationsRepository.getConversations();
  167. friends = await FriendsRepository.getFriends(accepted: true);
  168. friendRequests = await FriendsRepository.getFriends(accepted: false);
  169. profile = await MyProfile.getProfile();
  170. setState(() {
  171. _widgetOptions = <Widget>[
  172. ConversationList(
  173. conversations: conversations,
  174. friends: friends,
  175. ),
  176. FriendList(
  177. friends: friends,
  178. friendRequests: friendRequests,
  179. callback: reinitDatabaseRecords,
  180. ),
  181. Profile(profile: profile),
  182. ];
  183. isLoading = false;
  184. });
  185. }
  186. void _onItemTapped(int index) async {
  187. await reinitDatabaseRecords();
  188. setState(() {
  189. _selectedIndex = index;
  190. });
  191. }
  192. }