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.

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