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.7 KiB

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