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.

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