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.

206 lines
5.6 KiB

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