Ver Fonte

update to current state

idk how or why, but my past commits got corrupted so there's not much of a commit history of inbetween work
Juan Marulanda De Los Rios há 1 mês atrás
pai
commit
b96209c872
1 ficheiros alterados com 386 adições e 78 exclusões
  1. 386 78
      lib/api_service.dart

+ 386 - 78
lib/api_service.dart

@@ -1,93 +1,401 @@
-//api file
-
-
-// import 'package:http/http.dart' as http;
-// import 'dart:convert';
-
-// class SerializableMessage {
-//   final String name;
-//   final String from;
-//   final String path;
-//   final String subject;
-//   final String date;
-
-//   SerializableMessage({
-//     required this.name,
-//     required this.from,
-//     required this.path,
-//     required this.subject,
-//     required this.date,
-//   });
-
-//   factory SerializableMessage.fromJson(Map<String, dynamic> json) {
-//     return SerializableMessage(
-//       name: json['name'],
-//       from: json['from'],
-//       path: json['path'],
-//       subject: json['subject'],
-//       date: json['date'],
-//     );
-//   }
-// }
+import 'package:flutter/material.dart';
+import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
+// import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
+import 'package:http/http.dart' as http;
+import 'dart:convert';
+//TODO: copy hope_page.dart impl of iframe
+import 'dart:ui_web' as ui;
+import 'dart:html' as html;
+// import 'package:flutter_html/flutter_html.dart';
+
+class MailAddress {
+  final String? name;
+  final String address;
+  MailAddress({this.name, required this.address});
+
+  factory MailAddress.fromJson(Map<String, dynamic> json) {
+    return MailAddress(
+      name: json['name'],
+      address: json['address'],
+    );
+  }
+}
+
+class SerializableMessage {
+  final String name;
+  final String from;
+  final List<MailAddress> to;
+  final List<MailAddress> cc;
+  final String hash;
+
+  // final String path;
+  final String subject;
+  final String date;
+  final int uid;
+  final String list;
+  final String id;
+  final String in_reply_to;
+
+  SerializableMessage({
+    required this.name,
+    required this.from,
+    required this.to,
+    required this.cc,
+    required this.hash,
+    required this.subject,
+    required this.date,
+    required this.uid,
+    required this.list,
+    required this.id,
+    required this.in_reply_to,
+  });
+
+  factory SerializableMessage.fromJson(Map<String, dynamic> json) {
+    var toList = json['to'] as List;
+    var ccList = json['cc'] as List;
+
+    return SerializableMessage(
+      name: json['name'],
+      from: json['from'],
+      // to: json['name', 'address']
+      to: toList.map((i) => MailAddress.fromJson(i)).toList(),
+      cc: ccList.map((i) => MailAddress.fromJson(i)).toList(),
+      // path: json['path'],
+      hash: json['hash'],
+      subject: json['subject'],
+      date: json['date'],
+      uid: json['uid'],
+      list: json['list'],
+      id: json['id'],
+      in_reply_to: json['in_reply_to'],
+    );
+  }
+}
+
+class EmailPage extends StatefulWidget {
+  const EmailPage({super.key});
+  final String title = 'Emails';
+
+  @override
+  State<EmailPage> createState() => _EmailPageState();
+}
+
+class _EmailPageState extends State<EmailPage> {
+  List emails = [];
+
+  void _displayEmailsFromFolder(String folder) async {
+    // Map<String, List<SerializableMessage>> messagesMap = {};
+    List<SerializableMessage> allEmails = [];
+
+    try {
+      var url = Uri.http(
+          '127.0.0.1:3001', 'sorted_threads_by_date', {'folder': folder});
+      var response = await http.get(url);
+      // print(response.body);
+      // Map<String, dynamic> json = jsonDecode(response.body); original
+
+      // json.forEach((key, value) {
+      //   List<SerializableMessage> messages = (value as List)
+      //       .map((item) => SerializableMessage.fromJson(item))
+      //       .toList();
+      //   messagesMap[key] = messages;
+      // });
+
+      // new shit
+      if (response.statusCode == 200) {
+        List<dynamic> json = jsonDecode(response.body);
+        for (var item in json) {
+          if (item.length > 1 && item[0] is String && item[1] is List) {
+            //  print('Date: ${item[0]}, Threads: ${item[1]}');
+            List<int> threadIDs = List<int>.from(item[1]);
+            for (var threadId in threadIDs) {
+              await fetchThreadMessages(threadId, allEmails);
+            }
+          }
+        }
+      } else {
+        throw Exception('Failed to load threads');
+      }
+    } catch (e) {
+      print('_displayEmailsFromFolder caught error: $e');
+    }
+    setState(() {
+      emails.clear();
+      // emails = messagesMap.values.toList().expand((list) => list).toList();
+      emails.addAll(allEmails);
+      print(emails);
+      ;
+    });
+  }
+
+  Future<void> fetchThreadMessages(
+      int threadId, List<SerializableMessage> allEmails) async {
+    try {
+      var url = Uri.http(
+          '127.0.0.1:3001', 'get_thread_messages', {'id': threadId.toString()});
+      var response = await http.get(url);
+      if (response.statusCode == 200) {
+        List<dynamic> messagesJson = jsonDecode(response.body);
+        List<SerializableMessage> messages =
+            messagesJson.map((mj) => SerializableMessage.fromJson(mj)).toList();
+        allEmails.addAll(messages);
+      } else {
+        throw Exception(
+            'Failed to fetch thread messages for thread ID: $threadId');
+      }
+    } catch (e) {
+      print('Error fetching thread messages: $e');
+    }
+  }
+
+  Future<String> _getEmailContent(String relativePath) async {
+    String content = r"""
+
+    """;
+    try {
+      var url = Uri.http('127.0.0.1:3001', 'email', {'path': relativePath});
+      var response = await http.get(url);
+      if (response.statusCode == 200) {
+        print('ok');
+        content = response.body;
+      }
+    } catch (e) {
+      print('_getEmailContent caught error: $e');
+    }
+    // print(content);
+
+    return content;
+  }
+
+  Future<List<Widget>> _getDrawerItems() async {
+    List<String> drawerItems = [];
 
-// class ApiService {
-//   static const String baseUrl = '127.0.0.1:3001';
+    try {
+      var url = Uri.http('127.0.0.1:3001', 'folders');
+      var response = await http.get(url);
+      drawerItems = List<String>.from(json.decode(response.body));
+    } catch (e) {
+      print('_getDrawerItems caught error: $e');
+    }
 
-//   Future<Map<String, List<SerializableMessage>>> fetchEmailsByFolder(String folder) async {
-//     Map<String, List<SerializableMessage>> messagesMap = {};
+    List<Widget> drawerWidgets = [];
 
-//     try {
-//       var url = Uri.http(baseUrl, '/sorted_threads_by_date', {'folder': folder});
-//       var response = await http.get(url);
+    for (String item in drawerItems) {
+      drawerWidgets.add(
+        ListTile(
+          leading: Icon(Icons.mail),
+          title: Text(item),
+          onTap: () {
+            _displayEmailsFromFolder(item);
+            Navigator.pop(context);
+          },
+        ),
+      );
+    }
 
-//       if (response.statusCode == 200) {
-//         Map<String, dynamic> json = jsonDecode(response.body);
+    return drawerWidgets;
+  }
 
-//         json.forEach((key, value) {
-//           List<SerializableMessage> messages = (value as List)
-//               .map((item) => SerializableMessage.fromJson(item))
-//               .toList();
-//           messagesMap[key] = messages;
-//         });
-//       }
-//     } catch (e) {
-//       print('fetchEmailsByFolder caught error: $e');
-//     }
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+        title: Text(widget.title),
+      ),
+      drawer: Drawer(
+        child: FutureBuilder<List<Widget>>(
+          future:
+              _getDrawerItems(), // call the async function to get the future
+          builder:
+              (BuildContext context, AsyncSnapshot<List<Widget>> snapshot) {
+            if (snapshot.connectionState == ConnectionState.waiting) {
+              // While data is loading, show a progress indicator
+              return Center(child: CircularProgressIndicator());
+            } else if (snapshot.hasError) {
+              // If something went wrong, show an error message
+              return Center(child: Text('Error: ${snapshot.error}'));
+            } else {
+              // When data is fetched successfully, display the items
+              return ListView(
+                padding: EdgeInsets.zero,
+                children:
+                    snapshot.data!, // Unwrap the data once confirmed it's there
+              );
+            }
+          },
+        ),
+      ),
+      body: EmailListScreen(emails: emails, getEmailContent: _getEmailContent),
+    );
+  }
+}
 
-//     return messagesMap;
+class EmailListScreen extends StatelessWidget {
+  List emails;
+  final Future<String> Function(String) getEmailContent;
+
+  EmailListScreen({required this.emails, required this.getEmailContent});
+
+  @override
+  Widget build(BuildContext context) {
+    print(emails);
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('Emails'),
+      ),
+      body: ListView.separated(
+        itemCount: emails.length,
+        itemBuilder: (context, index) {
+          return ListTile(
+              title: Text(emails[index].from,
+                  style: TextStyle(fontWeight: FontWeight.bold)),
+              subtitle: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(emails[index].subject),
+                ],
+              ),
+              trailing: Text(emails[index].date.toString()),
+              onTap: () async {
+                String emailContent = await getEmailContent(emails[index].path);
+                Navigator.push(
+                  context,
+                  MaterialPageRoute(
+                      builder: (context) =>
+                          EmailView(emailContent: emailContent)),
+                );
+              });
+        },
+        separatorBuilder: (context, index) {
+          return Divider();
+        },
+      ),
+    );
+  }
+}
+
+class EmailView extends StatefulWidget {
+  final String emailContent;
+
+  const EmailView({Key? key, required this.emailContent}) : super(key: key);
+  @override
+  _EmailViewState createState() => _EmailViewState();
+
+  // @override
+  // void initState(){
+  //   ui.platformViewRegistry.registerViewFactory(
+  //         'html-view33',
+  //         (int viewId) => html.IFrameElement()
+  //       ..width = '100%'
+  //       ..height = '100%'
+  //       ..srcdoc = emailContent
+  //       ..style.border = 'none');
+}
+
+//   @override
+//   Widget build(BuildContext context) {
+//     return Scaffold(
+//       appBar: AppBar(
+//         title: Text('Email Content'),
+//       ),
+//       // body: SingleChildScrollView(
+//       //   child: Padding(
+//       //     padding: const EdgeInsets.all(16.0),
+//       //     child: HtmlWidget(
+//       //       emailContent,
+//       //       onErrorBuilder: (context, element, error) =>
+//       //           Text('$element error: $error'),
+//       //       onLoadingBuilder: (context, element, loadingProgress) =>
+//       //           CircularProgressIndicator(),
+//       //       renderMode: RenderMode.column,
+//       //       // webView: true,
+//       //     ),
+//       //   ),
+//       // ),
+//       // body: Center(
+//       //   child: Html(
+//       //     data: emailContent
+//       //     )
+//       //   ,
+//       // ),
+//       body: Center(
+//         child: HtmlElementView(viewType: 'html-view33',),
+//       ),
+
+//     );
 //   }
+// }
+
+// class HtmlContentWidget
+
+// class HtmlIFrameView extends StatelessWidget {
+//   final String emailContent;
 
-//   Future<List<String>> fetchFolders() async {
-//     List<String> folders = [];
+//   const HtmlIFrameView({required this.emailContent});
 
-//     try {
-//       var url = Uri.http(baseUrl, '/folders');
-//       var response = await http.get(url);
+//   @override
+//   Widget build(BuildContext context) {
+//     return HtmlElementView(viewType: 'html-view');
+//   }
+// }
+
+// class HtmlElementView extends StatelessWidget {
+//   final String emailContent;
 
-//       if (response.statusCode == 200) {
-//         folders = List<String>.from(json.decode(response.body));
-//       }
-//     } catch (e) {
-//       print('fetchFolders caught error: $e');
-//     }
+//   const HtmlElementView({required this.emailContent});
 
-//     return folders;
+//   @override
+//   Widget build(BuildContext context) {
+//     return IFrameElementWidget(emailContent: emailContent);
 //   }
+// }
+
+// class IFrameElementWidget extends StatelessWidget {
+//   final String emailContent;
+
+//   const IFrameElementWidget({required this.emailContent});
 
-//   Future<String> fetchEmailContent(String path) async {
-//     try {
-//       var url = Uri.http(baseUrl, path);
-//       var response = await http.get(url);
-
-//       if (response.statusCode == 200) {
-//         return response.body;
-//       } else {
-//         print('Failed to load email content');
-//       }
-//     } catch (e) {
-//       print('fetchEmailContent caught error: $e');
-//     }
-
-//     return '';
+//   @override
+//   Widget build(BuildContext context) {
+//     ui.platformViewRegistry.registerViewFactory(
+//       'html-view',
+//       (int viewId) => html.IFrameElement()
+//         ..width = '100%'
+//         ..height = '100%'
+//         ..srcdoc = emailContent
+//         ..style.border = 'none',
+//     );
+//     return HtmlElementView(
+//       viewType: 'html-view',
+//     );
 //   }
 // }
+
+class _EmailViewState extends State<EmailView> {
+  @override
+  void initState() {
+    super.initState();
+
+    ui.platformViewRegistry.registerViewFactory(
+      'html-view33',
+      (int viewId) => html.IFrameElement()
+        ..width = '100%'
+        ..height = '100%'
+        ..srcdoc = widget.emailContent
+        ..style.border = 'none',
+    );
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      appBar: AppBar(
+        title: Text('email content'),
+      ),
+      body: HtmlElementView(
+        viewType: 'html-view33',
+      ),
+    );
+  }
+}