added resulting listview for when emails are searched, (when each individual email is clicked it is not applied)
This commit is contained in:
		
							parent
							
								
									36c161cb55
								
							
						
					
					
						commit
						61c91b633b
					
				
					 4 changed files with 241 additions and 90 deletions
				
			
		| 
						 | 
				
			
			@ -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 [];
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
									
								
								lib/serialize.dart
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								lib/serialize.dart
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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(),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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'],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue