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.

151 lines
4.4 KiB

  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:http/http.dart' as http;
  4. import 'package:flutter_dotenv/flutter_dotenv.dart';
  5. import '/utils/storage/session_cookie.dart';
  6. import '/components/user_search_result.dart';
  7. import '/data_models/user_search.dart';
  8. class FriendAddSearch extends StatefulWidget {
  9. const FriendAddSearch({
  10. Key? key,
  11. }) : super(key: key);
  12. @override
  13. State<FriendAddSearch> createState() => _FriendAddSearchState();
  14. }
  15. class _FriendAddSearchState extends State<FriendAddSearch> {
  16. UserSearch? user;
  17. Text centerMessage = const Text('Search to add friends...');
  18. TextEditingController searchController = TextEditingController();
  19. @override
  20. Widget build(BuildContext context) {
  21. return Scaffold(
  22. appBar: AppBar(
  23. elevation: 0,
  24. automaticallyImplyLeading: false,
  25. flexibleSpace: SafeArea(
  26. child: Container(
  27. padding: const EdgeInsets.only(right: 16),
  28. child: Row(
  29. children: <Widget>[
  30. IconButton(
  31. onPressed: () {
  32. Navigator.pop(context);
  33. },
  34. icon: Icon(
  35. Icons.arrow_back,
  36. color: Theme.of(context).appBarTheme.iconTheme?.color,
  37. ),
  38. ),
  39. const SizedBox(width: 2),
  40. Expanded(
  41. child: Column(
  42. crossAxisAlignment: CrossAxisAlignment.start,
  43. mainAxisAlignment: MainAxisAlignment.center,
  44. children: <Widget>[
  45. Text(
  46. 'Add Friends',
  47. style: TextStyle(
  48. fontSize: 16,
  49. fontWeight: FontWeight.w600,
  50. color: Theme.of(context).appBarTheme.toolbarTextStyle?.color
  51. )
  52. ),
  53. ],
  54. )
  55. )
  56. ]
  57. ),
  58. ),
  59. ),
  60. ),
  61. body: Stack(
  62. children: <Widget>[
  63. Padding(
  64. padding: const EdgeInsets.only(top: 16,left: 16,right: 16),
  65. child: TextField(
  66. autofocus: true,
  67. decoration: InputDecoration(
  68. hintText: 'Search...',
  69. prefixIcon: const Icon(
  70. Icons.search,
  71. size: 20
  72. ),
  73. suffixIcon: Padding(
  74. padding: const EdgeInsets.only(top: 4, bottom: 4, right: 8),
  75. child: OutlinedButton(
  76. style: ButtonStyle(
  77. backgroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.secondary),
  78. foregroundColor: MaterialStateProperty.all(Theme.of(context).colorScheme.onSecondary),
  79. shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0))),
  80. elevation: MaterialStateProperty.all(4),
  81. ),
  82. onPressed: searchUsername,
  83. child: const Icon(Icons.search, size: 25),
  84. ),
  85. ),
  86. ),
  87. controller: searchController,
  88. ),
  89. ),
  90. Padding(
  91. padding: const EdgeInsets.only(top: 90),
  92. child: showFriend(),
  93. ),
  94. ],
  95. ),
  96. );
  97. }
  98. Widget showFriend() {
  99. if (user == null) {
  100. return Center(
  101. child: centerMessage,
  102. );
  103. }
  104. return UserSearchResult(
  105. user: user!,
  106. );
  107. }
  108. Future<void> searchUsername() async {
  109. if (searchController.text.isEmpty) {
  110. return;
  111. }
  112. Map<String, String> params = {};
  113. params['username'] = searchController.text;
  114. var uri = Uri.parse('${dotenv.env["SERVER_URL"]}api/v1/auth/users');
  115. uri = uri.replace(queryParameters: params);
  116. var resp = await http.get(
  117. uri,
  118. headers: {
  119. 'cookie': await getSessionCookie(),
  120. }
  121. );
  122. if (resp.statusCode != 200) {
  123. user = null;
  124. centerMessage = const Text('User not found');
  125. setState(() {});
  126. return;
  127. }
  128. user = UserSearch.fromJson(
  129. jsonDecode(resp.body)
  130. );
  131. setState(() {});
  132. FocusScope.of(context).unfocus();
  133. searchController.clear();
  134. }
  135. }