diff --git a/lib/api_service.dart b/lib/api_service.dart index b95f1c5..a4bdcfc 100644 --- a/lib/api_service.dart +++ b/lib/api_service.dart @@ -67,20 +67,34 @@ class ApiService { } } - Future> sonicSearch( + Future> 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 matches = List.from(json.decode(response.body)); - print(matches); - return matches; + List messagesJson = json.decode(response.body); + List messages = + messagesJson.map((mj) => SerializableMessage.fromJson(mj)).toList(); + + // messages[0].id; + // List messages = + // List.from(json.decode(response.body)); + // List 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 []; } diff --git a/lib/home_page.dart b/lib/home_page.dart index d068e80..24e30ed 100644 --- a/lib/home_page.dart +++ b/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 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 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> 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>( + future: apiService.sonicSearch("INBOX", 10, 0, query), + builder: (BuildContext context, AsyncSnapshot> 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 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); + 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 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 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, diff --git a/lib/serialize.dart b/lib/serialize.dart new file mode 100644 index 0000000..90719a8 --- /dev/null +++ b/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 { + List? messages; + bool isLoading = true; + bool hasError = false; + + final ApiService apiService = ApiService(); + + @override + void initState() { + super.initState(); + _fetchMessages(); + } + + Future _fetchMessages() async { + try { + List 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(), + ); + } +} diff --git a/lib/structs.dart b/lib/structs.dart index 40da3b7..9bc3ecf 100644 --- a/lib/structs.dart +++ b/lib/structs.dart @@ -52,52 +52,52 @@ class MailAddress { } } // //old data structure -// class SerializableMessage { -// final String name; -// final String from; -// final List to; -// final List cc; -// final String hash; +class SerializableMessage { + final String name; + final String from; + final List to; + final List 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 json) { -// var toList = json['to'] as List; -// var ccList = json['cc'] as List; + factory SerializableMessage.fromJson(Map 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'], -// ); -// } -// } \ No newline at end of file + 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'], + ); + } +} \ No newline at end of file