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.

172 lines
4.7 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: []),
  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(conversations: conversations),
  57. FriendList(friends: friends),
  58. Profile(profile: profile),
  59. ];
  60. isLoading = false;
  61. });
  62. }
  63. Future<bool> checkLogin() async {
  64. bool isLoggedIn = false;
  65. try {
  66. isLoggedIn = await MyProfile.isLoggedIn();
  67. } catch (Exception) {
  68. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  69. return false;
  70. }
  71. if (!isLoggedIn) {
  72. await MyProfile.logout();
  73. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  74. return false;
  75. }
  76. int statusCode = 200;
  77. try {
  78. var resp = await http.get(
  79. Uri.parse('${dotenv.env["SERVER_URL"]}api/v1/auth/check'),
  80. headers: {
  81. 'cookie': await getSessionCookie(),
  82. }
  83. );
  84. statusCode = resp.statusCode;
  85. } catch(SocketException) {
  86. if (await MyProfile.isLoggedIn()) {
  87. return true;
  88. }
  89. }
  90. if (isLoggedIn && statusCode == 200) {
  91. return true;
  92. }
  93. MyProfile.logout();
  94. Navigator.pushNamedAndRemoveUntil(context, '/landing', ModalRoute.withName('/landing'));
  95. return false;
  96. }
  97. void _onItemTapped(int index) {
  98. setState(() {
  99. _selectedIndex = index;
  100. });
  101. }
  102. Widget loading() {
  103. return Stack(
  104. children: <Widget>[
  105. const Opacity(
  106. opacity: 0.1,
  107. child: ModalBarrier(dismissible: false, color: Colors.black),
  108. ),
  109. Center(
  110. child: Column(
  111. mainAxisSize: MainAxisSize.max,
  112. mainAxisAlignment: MainAxisAlignment.center,
  113. children: const <Widget> [
  114. CircularProgressIndicator(),
  115. SizedBox(height: 25),
  116. Text("Loading..."),
  117. ],
  118. )
  119. ),
  120. ]
  121. );
  122. }
  123. @override
  124. Widget build(BuildContext context) {
  125. return WillPopScope(
  126. onWillPop: () async => false,
  127. child: isLoading ? loading() : Scaffold(
  128. body: _widgetOptions.elementAt(_selectedIndex),
  129. bottomNavigationBar: isLoading ? const SizedBox.shrink() : BottomNavigationBar(
  130. currentIndex: _selectedIndex,
  131. onTap: _onItemTapped,
  132. selectedItemColor: Theme.of(context).primaryColor,
  133. unselectedItemColor: Theme.of(context).hintColor,
  134. selectedLabelStyle: const TextStyle(fontWeight: FontWeight.w600),
  135. unselectedLabelStyle: const TextStyle(fontWeight: FontWeight.w600),
  136. type: BottomNavigationBarType.fixed,
  137. items: const [
  138. BottomNavigationBarItem(
  139. icon: Icon(Icons.message),
  140. label: "Chats",
  141. ),
  142. BottomNavigationBarItem(
  143. icon: Icon(Icons.group_work),
  144. label: "Friends",
  145. ),
  146. BottomNavigationBarItem(
  147. icon: Icon(Icons.account_box),
  148. label: "Profile",
  149. ),
  150. ],
  151. ),
  152. ),
  153. );
  154. }
  155. }