Browse Source

added resulting listview for when emails are searched, (when each individual email is clicked it is not applied)

juan 1 month ago
parent
commit
61c91b633b
4 changed files with 241 additions and 90 deletions
  1. 21 7
      lib/api_service.dart
  2. 90 38
      lib/home_page.dart
  3. 85 0
      lib/serialize.dart
  4. 45 45
      lib/structs.dart

+ 21 - 7
lib/api_service.dart

@@ -67,20 +67,34 @@ class ApiService {
     }
   }
 
-  Future<List<String>> sonicSearch(
+  Future<List<SerializableMessage>> sonicSearch(
       String list, int limit, int offset, String query) async {
     try {
-      var url = Uri.http('127.0.0.1:3001', 'search',
-          {'list': list, 'limit': limit.toString(), 'offset': offset.toString(), 'query': query});
+      var url = Uri.http('127.0.0.1:3001', 'search', {
+        'list': list,
+        'limit': limit.toString(),
+        'offset': offset.toString(),
+        'query': query
+      });
       var response = await http.get(url);
 
       if (response.statusCode == 200) {
-        List<String> matches = List<String>.from(json.decode(response.body));
-        print(matches);
-        return matches;
+        List<dynamic> messagesJson = json.decode(response.body);
+        List<SerializableMessage> messages =
+            messagesJson.map((mj) => SerializableMessage.fromJson(mj)).toList();
+
+        // messages[0].id;
+        // List<SerializableMessage> messages =
+        //     List<SerializableMessage>.from(json.decode(response.body));
+        //         List<SerializableMessage> messages =
+        // -            messagesJson.map((mj) => SerializableMessage.fromJson(mj)).toList();
+        // print("above mess");
+        
+        print(messages[0].uid);
+        return messages;
       }
     } catch (e) {
-      print(e);
+      print("caught $e");
     }
     return [];
   }

+ 90 - 38
lib/home_page.dart

@@ -1,8 +1,10 @@
 import 'package:crab_ui/folder_drawer.dart';
+import 'package:crab_ui/structs.dart';
 import 'package:flutter/widgets.dart';
 import 'api_service.dart';
 import 'package:flutter/material.dart';
 import 'email.dart';
+// import 'serialize.dart';
 
 class HomeScreen extends StatefulWidget {
   @override
@@ -34,8 +36,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
     setState(() {
       if (!_tabs.contains(query)) {
         _tabs.add(query);
-        _tabWidgets[query] = _buildSearchResultsWidget(
-            query); // Store a different widget for this tab
+        _tabWidgets[query] = _buildSearchResultsWidget(query); // Store a different widget for this tab
         _tabController = TabController(length: _tabs.length, vsync: this);
       }
     });
@@ -56,16 +57,91 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
 
   // Build a custom widget for each search query
   Widget _buildSearchResultsWidget(String query) {
-    return Center(
-      child: Column(
-        mainAxisAlignment: MainAxisAlignment.center,
-        children: [
-          Text("Results for: $query", style: TextStyle(fontSize: 24)),
-          // You can add a list or any custom widget here
-          Text("Here you can display search results or other content."),
-        ],
-      ),
-    );
+    // Future<List<SerializableMessage>> result = apiService.sonicSearch("INBOX", 10, 0, query);
+    // return Center(
+    //   child: Column(
+    //     mainAxisAlignment: MainAxisAlignment.center,
+    //     children: [
+    //       // Text("Results for: $query", style: TextStyle(fontSize: 24)),
+    //       // // You can add a list or any custom widget here
+    //       // Text("Here you can display search results or other content."),
+    //       // Text(result[0].messages.toString()),
+    //       Text(query),
+    //       Text(result[0].name),
+    //     ],
+    //   ),
+    // );
+    return FutureBuilder<List<SerializableMessage>>(
+    future: apiService.sonicSearch("INBOX", 10, 0, query),
+    builder: (BuildContext context, AsyncSnapshot<List<SerializableMessage>> snapshot) {
+      if (snapshot.connectionState == ConnectionState.waiting) {
+        return Center(child: CircularProgressIndicator());
+      } else if (snapshot.hasError) {
+        return Center(child: Text('Error: ${snapshot.error}'));
+      } else if (!snapshot.hasData || snapshot.data!.isEmpty) {
+        return Center(child: Text('No results found for: $query'));
+      } else {
+        List<SerializableMessage> result = snapshot.data!;
+        return Scaffold(
+          body: ListView.separated(
+            itemCount: result.length,
+            itemBuilder: (context, index){
+              final email = result[index];
+              return ListTile(
+              title: Text(email.from,
+                  style: TextStyle(fontWeight: FontWeight.bold)),
+              subtitle: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [Text(email.subject)],
+              ),
+              trailing: Text(email.date.toString()),
+              onTap: () async {
+                String emailContent = await apiService.fetchEmailContent(email.id as List<String>);
+                Navigator.push(
+                  context,
+                  MaterialPageRoute(
+                    builder: (context) => EmailView(
+                      emailContent: emailContent,
+                      from: email.from,
+                      name: email.name,
+                      to: email.to.toString(),
+                      subject: email.subject,
+                      date: email.date.toString(),
+                      id: email.id.toString(),
+                    ),
+                  ),
+                );
+              },
+              );
+            },
+              separatorBuilder: (context, index) => Divider(),
+            ),
+          // child: Column(
+          //   mainAxisAlignment: MainAxisAlignment.center,
+          //   children: [
+          //     Text("Results for: $query", style: TextStyle(fontSize: 24)),
+          //     // Display the actual data
+          //     Text(result[0].name), // Accessing the first result safely
+          //     Text(result[0].from), // Displaying the 'from' field as an example
+          //     Text(result[0].hash),
+          //     Text(result[0].subject),
+          //     Text(result[0].uid.toString()),
+          //     Text(result[0].list),
+          //     Text(result[0].id),
+              
+              
+          //     // Add more fields or customize the display
+          //     // SerializableEmailListScreen(emails: result, getEmailContent: getEmailContent)
+          //     // Expanded(
+
+          //     //   child: 
+          //     // ),
+            // ],
+          );
+        // );
+      }
+    },
+  );
   }
 
   @override
@@ -84,31 +160,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
           _emailPageKey.currentState?.updateSelectedFolder(folder);
         },
       ),
-      // appBar: AppBar(
-      //   title: Text('Search with Tabs'),
-      //   bottom: _tabs.isNotEmpty
-      //       ? TabBar(
-      //           controller: _tabController,
-      //           isScrollable: true,
-      //           tabs: _tabs
-      //               .asMap()
-      //               .entries
-      //               .map((entry) => Tab(
-      //                     child: Row(
-      //                       children: [
-      //                         Text(entry.value),
-      //                         SizedBox(width: 8),
-      //                         GestureDetector(
-      //                           onTap: () => _removeTab(entry.key),
-      //                           child: Icon(Icons.close, size: 16),
-      //                         ),
-      //                       ],
-      //                     ),
-      //                   ))
-      //               .toList(),
-      //         )
-      //       : null,
-      // ),
+
       body: Stack(
         children: [
           Row(
@@ -264,7 +316,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
                         controller: _tabController,
                         children: _tabs.map((tab) {
                           return _tabWidgets[tab] ??
-                              Center(child: Text("No content found"));
+                            Center(child: Text("No content found"));
                           // return Center(
                           //     child: EmailPage(
                           //   key: _emailPageKey,

+ 85 - 0
lib/serialize.dart

@@ -0,0 +1,85 @@
+import 'package:flutter/material.dart';
+import 'api_service.dart';
+import 'structs.dart';
+
+class SerializableMessageListScreen extends StatefulWidget {
+  @override
+  _SerializableMessageListScreenState createState() => _SerializableMessageListScreenState();
+}
+
+class _SerializableMessageListScreenState extends State<SerializableMessageListScreen> {
+  List<SerializableMessage>? messages;
+  bool isLoading = true;
+  bool hasError = false;
+
+  final ApiService apiService = ApiService();
+
+  @override
+  void initState() {
+    super.initState();
+    _fetchMessages();
+  }
+
+  Future<void> _fetchMessages() async {
+    try {
+      List<SerializableMessage> fetchedMessages = await apiService.sonicSearch("INBOX", 10, 0, "searchQuery");
+      setState(() {
+        messages = fetchedMessages;
+        isLoading = false;
+      });
+    } catch (e) {
+      setState(() {
+        hasError = true;
+        isLoading = false;
+      });
+    }
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    if (isLoading) {
+      return Center(child: CircularProgressIndicator());
+    }
+
+    if (hasError) {
+      return Center(child: Text("Error fetching messages."));
+    }
+
+    if (messages == null || messages!.isEmpty) {
+      return Center(child: Text("No messages found."));
+    }
+
+    return ListView.separated(
+      itemCount: messages!.length,
+      itemBuilder: (context, index) {
+        final message = messages![index];
+        return ListTile(
+          title: Text(message.name, style: TextStyle(fontWeight: FontWeight.bold)),
+          subtitle: Column(
+            crossAxisAlignment: CrossAxisAlignment.start,
+            children: [Text(message.subject)],
+          ),
+          trailing: Text(message.date),
+          onTap: () async {
+            String emailContent = await apiService.fetchEmailContent([message.id]);
+            Navigator.push(
+              context,
+              MaterialPageRoute(
+                builder: (context) => EmailView(
+                  emailContent: emailContent,
+                  from: message.from,
+                  name: message.name,
+                  to: message.to.toString(),
+                  subject: message.subject,
+                  date: message.date,
+                  id: message.id,
+                ),
+              ),
+            );
+          },
+        );
+      },
+      separatorBuilder: (context, index) => Divider(),
+    );
+  }
+}

+ 45 - 45
lib/structs.dart

@@ -52,52 +52,52 @@ class MailAddress {
   }
 }
 // //old data structure
-// class SerializableMessage {
-//   final String name;
-//   final String from;
-//   final List<MailAddress> to;
-//   final List<MailAddress> cc;
-//   final String hash;
+class SerializableMessage {
+  final String name;
+  final String from;
+  final List<MailAddress> to;
+  final List<MailAddress> cc;
+  final String hash;
 
-//   final String subject;
-//   final String date;
-//   final int uid;
-//   final String list;
-//   final String id;
-//   final String in_reply_to;
+  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,
-//   });
+  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;
+  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'],
-//     );
-//   }
-// }
+    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'],
+    );
+  }
+}