api_service.dart 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. // this file should handle most of the API calls
  2. // it also builds some widgets, but it will be modulated later
  3. import 'package:crab_ui/structs.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:http/http.dart' as http;
  6. import 'dart:convert';
  7. import 'dart:ui_web' as ui;
  8. import 'augment.dart';
  9. import 'dart:html' as html;
  10. class ApiService {
  11. Future<List<GetThreadResponse>> fetchEmailsFromFolder(
  12. String folder, int pagenitaion) async {
  13. try {
  14. var url = Uri.http('127.0.0.1:3001', 'sorted_threads_by_date', {
  15. 'folder': folder,
  16. 'limit': '50',
  17. 'offset': pagenitaion.toString(),
  18. });
  19. var response = await http.get(url);
  20. // print(response);
  21. List<GetThreadResponse> allEmails = [];
  22. if (response.statusCode == 200) {
  23. List json = jsonDecode(response.body);
  24. for (var item in json) {
  25. //each item in the json is a date
  26. if (item.length > 1 && item[0] is String && item[1] is List) {
  27. List<int> threadIDs = List<int>.from(item[1]);
  28. for (var threadId in threadIDs) {
  29. await fetchThreads(threadId, allEmails);
  30. }
  31. }
  32. }
  33. return allEmails;
  34. } else {
  35. throw Exception('Failed to load threads');
  36. }
  37. } catch (e) {
  38. print('_displayEmailsFromFolder caught error: $e');
  39. return [];
  40. }
  41. }
  42. Future<void> fetchThreads(
  43. //populates allEmails, which is the List that contains all the emails in a thread
  44. int threadId,
  45. List<GetThreadResponse> allEmails) async {
  46. try {
  47. var url =
  48. Uri.http('127.0.0.1:3001', 'get_thread', {'id': threadId.toString()});
  49. var response = await http.get(url);
  50. if (response.statusCode == 200) {
  51. Map<String, dynamic> messagesJson = jsonDecode(response.body);
  52. GetThreadResponse threadResponse =
  53. GetThreadResponse.fromJson(messagesJson);
  54. allEmails.add(threadResponse);
  55. } else {
  56. throw Exception(
  57. 'Failed to fetch thread messages for thread ID: $threadId');
  58. }
  59. } catch (e) {
  60. print('Error fetching thread messages: $e');
  61. }
  62. }
  63. Future<List<SerializableMessage>> sonicSearch(
  64. String list, int limit, int offset, String query) async {
  65. try {
  66. var url = Uri.http('127.0.0.1:3001', 'search', {
  67. 'list': list,
  68. 'limit': limit.toString(),
  69. 'offset': offset.toString(),
  70. 'query': query
  71. });
  72. var response = await http.get(url);
  73. if (response.statusCode == 200) {
  74. List<dynamic> messagesJson = json.decode(response.body);
  75. List<SerializableMessage> messages =
  76. messagesJson.map((mj) => SerializableMessage.fromJson(mj)).toList();
  77. return messages;
  78. }
  79. } catch (e) {
  80. print("caught $e");
  81. }
  82. return [];
  83. }
  84. Future<String> fetchEmailContent(List<String> IDs) async {
  85. String content = r"""
  86. """;
  87. try {
  88. //attaches email after email from a thread
  89. for (var id in IDs) {
  90. var url = Uri.http('127.0.0.1:3001', 'email', {'id': id});
  91. var response = await http.get(url);
  92. if (response.statusCode == 200) {
  93. content += response.body;
  94. content += "<hr>";
  95. }
  96. }
  97. } catch (e) {
  98. print('_getEmailContent caught error: $e');
  99. }
  100. return content;
  101. }
  102. // void _addMailBox async(BuildContext context){
  103. // //add email folder
  104. // showDialog(context: context, builder: builder)
  105. // }
  106. Future<List<String>> fetchFolders() async {
  107. try {
  108. var url = Uri.http('127.0.0.1:3001', 'folders');
  109. var response = await http.get(url);
  110. return List<String>.from(json.decode(response.body));
  111. } catch (e) {
  112. print('fetchFolders caught error: $e');
  113. return [];
  114. }
  115. }
  116. Future<void> createFolder(String folderName) async {
  117. var url = Uri.http('127.0.0.1:3001', 'create_folder');
  118. Map<String, String> requestBody = {'name': folderName};
  119. try {
  120. var response = await http.post(
  121. url,
  122. headers: {
  123. 'Content-Type': 'application/json',
  124. },
  125. body: jsonEncode(requestBody),
  126. );
  127. if (response.statusCode == 200) {
  128. print('response body: ${response.body}');
  129. } else {
  130. print('Error: ${response.statusCode}, response body: ${response.body}');
  131. }
  132. } catch (e) {
  133. print('error making post req: $e');
  134. }
  135. }
  136. Future<void> deleteFolder(String folderName) async {
  137. var url = Uri.http('127.0.0.1:3001', 'delete_folder');
  138. Map<String, String> requestBody = {'name': folderName};
  139. try {
  140. var response = await http.post(
  141. url,
  142. headers: {
  143. 'Content-Type': 'application/json',
  144. },
  145. body: jsonEncode(requestBody),
  146. );
  147. if (response.statusCode == 200) {
  148. print('response body: ${response.body}');
  149. } else {
  150. print('Error: ${response.statusCode}, response body: ${response.body}');
  151. }
  152. } catch (e) {
  153. print('error making post req: $e');
  154. }
  155. }
  156. }
  157. class EmailView extends StatefulWidget {
  158. final String emailContent;
  159. final String from;
  160. final String name;
  161. final String to;
  162. final String subject;
  163. final String date;
  164. final String id;
  165. const EmailView({
  166. Key? key,
  167. required this.emailContent,
  168. required this.from,
  169. required this.name,
  170. required this.to,
  171. required this.subject,
  172. required this.date,
  173. required this.id,
  174. }) : super(key: key);
  175. @override
  176. _EmailViewState createState() => _EmailViewState();
  177. }
  178. class _EmailViewState extends State<EmailView> {
  179. late Key iframeKey;
  180. late String currentContent;
  181. late String viewTypeId;
  182. // TextEditingController _jumpController = TextEditingController();
  183. @override
  184. void initState() {
  185. super.initState();
  186. String currentContent = widget.emailContent;
  187. viewTypeId = "iframe-${DateTime.now().millisecondsSinceEpoch}";
  188. _registerViewFactory(currentContent);
  189. }
  190. void _registerViewFactory(String currentContent) {
  191. setState(() {
  192. viewTypeId = 'iframe-${DateTime.now().millisecondsSinceEpoch}';
  193. ui.platformViewRegistry.registerViewFactory(
  194. viewTypeId,
  195. (int viewId) => html.IFrameElement()
  196. ..width = '100%'
  197. ..height = '100%'
  198. ..srcdoc = currentContent
  199. ..style.border = 'none');
  200. });
  201. }
  202. void _scrollToNumber(String spanId) {
  203. AugmentClasses.handleJump(spanId);
  204. }
  205. // TODO: void _invisibility(String )
  206. @override
  207. Widget build(BuildContext context) {
  208. // print(currentContent);
  209. return Scaffold(
  210. appBar: AppBar(
  211. title: Text(widget.name),
  212. ),
  213. body: Column(
  214. children: [
  215. EmailToolbar(
  216. onJumpToSpan: _scrollToNumber,
  217. onButtonPressed: () => {},
  218. // AugmentClasses.handleJump(viewTypeId, '1');
  219. // print("button got pressed?");
  220. // _registerViewFactory(r"""
  221. // <h1>Welcome to My Website</h1>
  222. // <p>This is a simple HTML page.</p>
  223. // <h2>What is HTML?</h2>
  224. // <p>HTML (HyperText Markup Language) is the most basic building block of the Web. It defines the meaning and structure of web content. Other technologies besides HTML are generally used to describe a web page's appearance/presentation (CSS) or functionality/behavior (JavaScript).</p>
  225. // <h3>Here's a simple list:</h3>
  226. // <ul>
  227. // <li>HTML elements are the building blocks of HTML pages</li>
  228. // <li>HTML uses tags like <code>&lt;tag&gt;</code> to organize and format content</li>
  229. // <li>CSS is used with HTML to style pages</li>
  230. // </ul>
  231. // <p>Copyright © 2023</p>
  232. // """);
  233. // print("change");
  234. // widget.emailContent = r"
  235. // "
  236. // },
  237. ),
  238. Row(
  239. // title of email
  240. children: [
  241. Text(
  242. widget.subject,
  243. style: TextStyle(fontSize: 30),
  244. ),
  245. ],
  246. ),
  247. Row(
  248. children: [
  249. Text(
  250. 'from ${widget.name}',
  251. style: TextStyle(fontSize: 18),
  252. ),
  253. Text(
  254. '<${widget.from}>',
  255. style: TextStyle(fontSize: 18),
  256. ),
  257. Spacer(),
  258. Text(
  259. '${widget.date}',
  260. textAlign: TextAlign.right,
  261. )
  262. ],
  263. ),
  264. // TODO: make a case where if one of these is the user's email it just says me :)))))
  265. Row(
  266. children: [
  267. Text(
  268. 'to ${widget.to.toString()}',
  269. style: TextStyle(fontSize: 15),
  270. )
  271. ],
  272. ),
  273. Expanded(
  274. child: HtmlElementView(
  275. key: UniqueKey(),
  276. viewType: viewTypeId,
  277. ),
  278. ),
  279. ],
  280. ));
  281. }
  282. }