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.

175 lines
4.8 KiB

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