|
@@ -1,3 +1,6 @@
|
|
|
|
+// this file should handle most of the API calls
|
|
|
|
+// it also builds some widgets, but it will be modulated later
|
|
|
|
+
|
|
import 'package:crab_ui/structs.dart';
|
|
import 'package:crab_ui/structs.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:http/http.dart' as http;
|
|
@@ -6,48 +9,25 @@ import 'dart:ui_web' as ui;
|
|
import 'augment.dart';
|
|
import 'augment.dart';
|
|
import 'dart:html' as html;
|
|
import 'dart:html' as html;
|
|
|
|
|
|
-//data structure
|
|
|
|
-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'],
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @override
|
|
|
|
- String toString() {
|
|
|
|
- // TODO: implement toString
|
|
|
|
- return '${name} <${address}>';
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-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 {
|
|
|
|
- List<GetThreadResponse> allEmails = []; //all the emails
|
|
|
|
|
|
+class ApiService {
|
|
|
|
+ // List emails = [];
|
|
|
|
|
|
|
|
+ Future<List<GetThreadResponse>> fetchEmailsFromFolder(
|
|
|
|
+ String folder, int pagenitaion) async {
|
|
try {
|
|
try {
|
|
- var url = Uri.http('127.0.0.1:3001', 'sorted_threads_by_date',
|
|
|
|
- {'folder': folder, 'limit': '10', 'offset': '0'});
|
|
|
|
|
|
+ var url = Uri.http('127.0.0.1:3001', 'sorted_threads_by_date', {
|
|
|
|
+ 'folder': folder,
|
|
|
|
+ 'limit': '20',
|
|
|
|
+ 'offset': pagenitaion.toString(),
|
|
|
|
+ });
|
|
var response = await http.get(url);
|
|
var response = await http.get(url);
|
|
- print(response);
|
|
|
|
|
|
+ // print(response);
|
|
|
|
+ List<GetThreadResponse> allEmails = [];
|
|
|
|
+
|
|
if (response.statusCode == 200) {
|
|
if (response.statusCode == 200) {
|
|
List json = jsonDecode(response.body);
|
|
List json = jsonDecode(response.body);
|
|
- for (var item in json.take(1)) {
|
|
|
|
|
|
+ for (var item in json) {
|
|
//each item in the json is a date
|
|
//each item in the json is a date
|
|
if (item.length > 1 && item[0] is String && item[1] is List) {
|
|
if (item.length > 1 && item[0] is String && item[1] is List) {
|
|
List<int> threadIDs = List<int>.from(item[1]);
|
|
List<int> threadIDs = List<int>.from(item[1]);
|
|
@@ -56,21 +36,25 @@ class EmailPageState extends State<EmailPage> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ return allEmails;
|
|
} else {
|
|
} else {
|
|
throw Exception('Failed to load threads');
|
|
throw Exception('Failed to load threads');
|
|
}
|
|
}
|
|
} catch (e) {
|
|
} catch (e) {
|
|
print('_displayEmailsFromFolder caught error: $e');
|
|
print('_displayEmailsFromFolder caught error: $e');
|
|
|
|
+ return [];
|
|
}
|
|
}
|
|
print("Done");
|
|
print("Done");
|
|
|
|
|
|
- setState(() {
|
|
|
|
- emails = allEmails;
|
|
|
|
- });
|
|
|
|
|
|
+ // setState(() {
|
|
|
|
+ // emails = allEmails;
|
|
|
|
+ // });
|
|
}
|
|
}
|
|
|
|
|
|
Future<void> fetchThreads(
|
|
Future<void> fetchThreads(
|
|
- int threadId, List<GetThreadResponse> allEmails) async {
|
|
|
|
|
|
+ //populates allEmails, which is the List that contains all the emails in a thread
|
|
|
|
+ int threadId,
|
|
|
|
+ List<GetThreadResponse> allEmails) async {
|
|
try {
|
|
try {
|
|
var url =
|
|
var url =
|
|
Uri.http('127.0.0.1:3001', 'get_thread', {'id': threadId.toString()});
|
|
Uri.http('127.0.0.1:3001', 'get_thread', {'id': threadId.toString()});
|
|
@@ -91,7 +75,7 @@ class EmailPageState extends State<EmailPage> {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- Future<String> _getEmailContent(List<String> IDs) async {
|
|
|
|
|
|
+ Future<String> fetchEmailContent(List<String> IDs) async {
|
|
String content = r"""
|
|
String content = r"""
|
|
""";
|
|
""";
|
|
|
|
|
|
@@ -104,7 +88,7 @@ class EmailPageState extends State<EmailPage> {
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
if (response.statusCode == 200) {
|
|
content += response.body;
|
|
content += response.body;
|
|
- content += "<p>end of mail</p><br><br><br>";
|
|
|
|
|
|
+ content += "<p>end of mail</p><br><br><br><hr>";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
} catch (e) {
|
|
@@ -113,136 +97,20 @@ class EmailPageState extends State<EmailPage> {
|
|
return content;
|
|
return content;
|
|
}
|
|
}
|
|
|
|
|
|
- Future<List<Widget>> getDrawerItems(BuildContext context) async {
|
|
|
|
- List<String> drawerItems = [];
|
|
|
|
|
|
+ // void _addMailBox async(BuildContext context){
|
|
|
|
+ // //add email folder
|
|
|
|
+ // showDialog(context: context, builder: builder)
|
|
|
|
+ // }
|
|
|
|
|
|
|
|
+ Future<List<String>> fetchFolders() async {
|
|
try {
|
|
try {
|
|
var url = Uri.http('127.0.0.1:3001', 'folders');
|
|
var url = Uri.http('127.0.0.1:3001', 'folders');
|
|
var response = await http.get(url);
|
|
var response = await http.get(url);
|
|
- drawerItems = List<String>.from(json.decode(response.body));
|
|
|
|
|
|
+ return List<String>.from(json.decode(response.body));
|
|
} catch (e) {
|
|
} catch (e) {
|
|
- print('getDrawerItems caught error: $e');
|
|
|
|
|
|
+ print('fetchFolders caught error: $e');
|
|
|
|
+ return [];
|
|
}
|
|
}
|
|
-
|
|
|
|
- List<Widget> drawerWidgets = [];
|
|
|
|
-
|
|
|
|
- for (String item in drawerItems) {
|
|
|
|
- drawerWidgets.add(
|
|
|
|
- ListTile(
|
|
|
|
- leading: Icon(Icons.mail),
|
|
|
|
- title: Text(item),
|
|
|
|
- onTap: () {
|
|
|
|
- _displayEmailsFromFolder(item);
|
|
|
|
- Navigator.pop(context);
|
|
|
|
- },
|
|
|
|
- ),
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return drawerWidgets;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @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(
|
|
|
|
- context), // 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,
|
|
|
|
- // getJsonEmail: _getThreadMessagesJson
|
|
|
|
- ),
|
|
|
|
- );
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-class EmailListScreen extends StatelessWidget {
|
|
|
|
- //this is the bulding of the drawer with all emails
|
|
|
|
- // try to only get the subject and id, date, sender to make it faster
|
|
|
|
- final List emails;
|
|
|
|
- final Future<String> Function(List<String>) getEmailContent;
|
|
|
|
-
|
|
|
|
- EmailListScreen({
|
|
|
|
- required this.emails,
|
|
|
|
- required this.getEmailContent,
|
|
|
|
- });
|
|
|
|
- // instead of getting the entire email, just the from, text, subject, and id
|
|
|
|
- @override
|
|
|
|
- Widget build(BuildContext context) {
|
|
|
|
- return Scaffold(
|
|
|
|
- appBar: AppBar(
|
|
|
|
- title: Text('Emails'),
|
|
|
|
- ),
|
|
|
|
- body: ListView.separated(
|
|
|
|
- itemCount: emails.length,
|
|
|
|
- itemBuilder: (context, index) {
|
|
|
|
- return ListTile(
|
|
|
|
- title: Text(emails[index].from_name,
|
|
|
|
- style: TextStyle(fontWeight: FontWeight.bold)),
|
|
|
|
- subtitle: Column(
|
|
|
|
- crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
- children: [
|
|
|
|
- Text(emails[index].subject),
|
|
|
|
- ],
|
|
|
|
- ),
|
|
|
|
- trailing: Text(emails[index].date.toString()),
|
|
|
|
- //here we assign each part of json to a var, this could be changed so it only happens,
|
|
|
|
- // when clicking on email for modularity
|
|
|
|
- onTap: () async {
|
|
|
|
- String emailContent =
|
|
|
|
- await getEmailContent(emails[index].messages);
|
|
|
|
- String fromName = emails[index].from_name.toString();
|
|
|
|
- String fromAddress = emails[index].from_address.toString();
|
|
|
|
- String to = emails[index].to.toString();
|
|
|
|
- String subject = emails[index].subject.toString();
|
|
|
|
- String date = emails[index].date.toString();
|
|
|
|
- String id = emails[index].id.toString();
|
|
|
|
-
|
|
|
|
- Navigator.push(
|
|
|
|
- context,
|
|
|
|
- MaterialPageRoute(
|
|
|
|
- builder: (context) => EmailView(
|
|
|
|
- emailContent: emailContent,
|
|
|
|
- from: fromAddress,
|
|
|
|
- name: fromName,
|
|
|
|
- to: to,
|
|
|
|
- subject: subject,
|
|
|
|
- date: date,
|
|
|
|
- id: id,
|
|
|
|
- )),
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
- },
|
|
|
|
- separatorBuilder: (context, index) {
|
|
|
|
- return Divider();
|
|
|
|
- },
|
|
|
|
- ),
|
|
|
|
- );
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|