Compare commits

...

2 Commits

2 changed files with 167 additions and 58 deletions

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:markdown/markdown.dart' as md;
import 'api_service.dart'; import 'api_service.dart';
import 'structs.dart'; import 'structs.dart';
import 'emailView.dart'; import 'emailView.dart';
@ -8,24 +9,28 @@ class EmailListScreen extends StatefulWidget {
final Future<List<String>> Function(List<String>, String) getEmailContent; final Future<List<String>> Function(List<String>, String) getEmailContent;
final String folder; final String folder;
final GlobalKey<_EmailListScreenState> key; final GlobalKey<_EmailListScreenState> key;
final Function(List<GetThreadResponse>)? onSelectionChanged;
EmailListScreen( EmailListScreen({
{required this.key, required this.key,
required this.emails, required this.emails,
required this.getEmailContent, required this.getEmailContent,
required this.folder}) required this.folder,
: super(key: key); this.onSelectionChanged,
}) : super(key: key);
@override @override
_EmailListScreenState createState() => _EmailListScreenState(); _EmailListScreenState createState() => _EmailListScreenState();
} }
class _EmailListScreenState extends State<EmailListScreen> { class _EmailListScreenState extends State<EmailListScreen>
with TickerProviderStateMixin {
late List<bool> selectStates; // for checkboxes if its selected or not late List<bool> selectStates; // for checkboxes if its selected or not
late List<GetThreadResponse> selectedEmails = late List<GetThreadResponse> selectedEmails =
[]; // holds the emails that are selected i.e. the emails that got the checkbox on []; // holds the emails that are selected i.e. the emails that got the checkbox on
final Set<int> _hoveredRows = {}; //the row that is being hovered over atm final Set<int> _hoveredRows = {}; //the row that is being hovered over atm
bool bulkSelectMenu = false; bool bulkSelectMenu = false;
final GlobalKey<EmailPageState> _emailPageKey = GlobalKey<EmailPageState>();
@override @override
void initState() { void initState() {
@ -42,21 +47,57 @@ class _EmailListScreenState extends State<EmailListScreen> {
} }
bool selectAllChecks(bool selectionType) { bool selectAllChecks(bool selectionType) {
//perhaps it should return a list of the selected
setState(() { setState(() {
selectedEmails = [];
if (selectionType) { if (selectionType) {
bulkSelectMenu = true; bulkSelectMenu = true;
} for (int email = 0; email < selectStates.length; email++) {
for (int email = 0; email < selectStates.length; email++) { selectStates[email] = selectionType;
selectStates[email] = selectionType; selectedEmails.add(widget.emails[email]);
}
} else {
for (int email = 0; email < selectStates.length; email++) {
selectStates[email] = selectionType;
}
selectedEmails = [];
} }
}); });
widget.onSelectionChanged?.call(selectedEmails);
printTheSelected(); printTheSelected();
return false; return false;
} }
bool markAsRead(bool read) {
print("markasread $read");
setState(() {
if (read) {
//read
for (int email = 0; email < selectedEmails.length; email++) {
selectedEmails[email].seen = read;
ApiService()
.markAsSeen(selectedEmails[email].id); //the remote or .json
}
} else {
//unread
for (int email = 0; email < selectedEmails.length; email++) {
selectedEmails[email].seen = read;
ApiService()
.markAsUnseen(selectedEmails[email].id); //the remote or .json
print(selectedEmails[email].subject);
}
}
});
return false;
}
List<GetThreadResponse> listOfSelectedThreads() {
return selectedEmails;
}
void printTheSelected() { void printTheSelected() {
for (int i = 0; i < selectedEmails.length; i++) { for (int i = 0; i < selectedEmails.length; i++) {
print(selectedEmails); print(selectedEmails[i].subject);
} }
} }
@ -83,11 +124,19 @@ class _EmailListScreenState extends State<EmailListScreen> {
setState(() { setState(() {
//works great //works great
selectStates[index] = value ?? false; selectStates[index] = value ?? false;
if (value!) {
selectedEmails.add(widget.emails[index]); setState(() {
} else { if (value!) {
selectedEmails.remove(widget.emails[index]); selectedEmails.add(widget.emails[index]);
} //here i must update the other side
_emailPageKey.currentState?.getListOfSelected();
} else {
selectedEmails.remove(widget.emails[index]);
_emailPageKey.currentState?.getListOfSelected();
}
widget.onSelectionChanged?.call(selectedEmails);
print(selectedEmails);
});
}); });
}, },
), ),
@ -97,7 +146,6 @@ class _EmailListScreenState extends State<EmailListScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(email.subject)], children: [Text(email.subject)],
), ),
// tileColor: () ,
trailing: _hoveredRows.contains(index) trailing: _hoveredRows.contains(index)
? Row( ? Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -161,10 +209,12 @@ class _EmailListScreenState extends State<EmailListScreen> {
// ignore: must_be_immutable // ignore: must_be_immutable
class EmailPage extends StatefulWidget { class EmailPage extends StatefulWidget {
EmailPage({Key? key}) : super(key: key);
String selectedFolder = "INBOX"; //starter String selectedFolder = "INBOX"; //starter
int offset = 0; int offset = 0;
int page = 1; int page = 1;
final Function(List<GetThreadResponse>)? onSelectionChanged;
EmailPage({Key? key, this.onSelectionChanged}) : super(key: key);
@override @override
EmailPageState createState() => EmailPageState(); EmailPageState createState() => EmailPageState();
@ -239,9 +289,19 @@ class EmailPageState extends State<EmailPage> {
bool selectAllEmails(bool selectionType) { bool selectAllEmails(bool selectionType) {
emailListKey.currentState?.selectAllChecks(selectionType); emailListKey.currentState?.selectAllChecks(selectionType);
return false; return selectionType;
} }
bool markSelectedAsRead(bool selectionType) {
emailListKey.currentState?.markAsRead(selectionType);
return selectionType;
}
List<GetThreadResponse> getListOfSelected() {
return emailListKey.currentState!.listOfSelectedThreads() ?? [];
}
// return [GetThreadResponse(id: 1, messages: [], subject: "subject", date: DateTime(2025), from_name: "from_name", from_address: "from_address", to: [], seen: false)];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -251,6 +311,7 @@ class EmailPageState extends State<EmailPage> {
// getEmailContent: apiService.fetchEmailContent, // getEmailContent: apiService.fetchEmailContent,
getEmailContent: apiService.fetchMarkdownContent, getEmailContent: apiService.fetchMarkdownContent,
folder: widget.selectedFolder, //try to grab from it directly folder: widget.selectedFolder, //try to grab from it directly
onSelectionChanged: widget.onSelectionChanged,
)); ));
} }
} }

View File

@ -29,6 +29,8 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
]; ];
bool _checkboxState = false; bool _checkboxState = false;
bool bulkOptionsState = false; bool bulkOptionsState = false;
List<GetThreadResponse> selectedThreads =
[]; //this should store the emails that are being stored downstream too
List<String> _tabs = ['Emails']; List<String> _tabs = ['Emails'];
Map<String, Widget> _tabWidgets = {}; Map<String, Widget> _tabWidgets = {};
@ -40,6 +42,11 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
_tabController = TabController(length: _tabs.length, vsync: this); _tabController = TabController(length: _tabs.length, vsync: this);
_tabWidgets['Emails'] = EmailPage( _tabWidgets['Emails'] = EmailPage(
key: _emailPageKey, key: _emailPageKey,
onSelectionChanged: (updatedList) {
setState(() {
selectedThreads = updatedList;
});
},
); );
} }
@ -354,24 +361,45 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
Icons.arrow_drop_down_outlined), Icons.arrow_drop_down_outlined),
itemBuilder: (BuildContext context) => itemBuilder: (BuildContext context) =>
<PopupMenuEntry<String>>[ <PopupMenuEntry<String>>[
const PopupMenuItem<String>( PopupMenuItem<String>(
child: Text("All")), //select all
const PopupMenuItem<String>( child: Text("All"),
child: Text("None")), onTap: () {
const PopupMenuItem<String>( _emailPageKey.currentState!
child: Text("Read")), .selectAllEmails(true);
const PopupMenuItem<String>( },
child: Text("Unread")), ),
const PopupMenuItem<String>( PopupMenuItem<String>(
child: Text("None"),
onTap: () {
_emailPageKey.currentState!
.selectAllEmails(false);
},
),
PopupMenuItem<String>(
child: Text("Read"),
onTap: () {
//select the read
},
),
PopupMenuItem<String>(
//select the unread
child: Text("Unread"),
onTap: () {
//select the unread
},
),
PopupMenuItem<String>(
child: Text("Starred")), child: Text("Starred")),
const PopupMenuItem<String>( PopupMenuItem<String>(
child: Text("Unstarred")), child: Text("Unstarred")),
], ],
onSelected: (String result) { onSelected: (String result) {
print("result $result"); print("result $result");
}, },
), ),
if (bulkOptionsState) ...<Widget>[ if (selectedThreads.isNotEmpty) ...<Widget>[
//this needs to know if anything got selected,
IconButton( IconButton(
onPressed: null, onPressed: null,
icon: Icon(Icons.archive_outlined)), icon: Icon(Icons.archive_outlined)),
@ -379,7 +407,11 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
onPressed: null, onPressed: null,
icon: Icon(Icons.delete_outlined)), icon: Icon(Icons.delete_outlined)),
IconButton( IconButton(
onPressed: null, onPressed: () {
_emailPageKey.currentState!
.markSelectedAsRead(
true); //mark as read
},
icon: Icon( icon: Icon(
Icons.mark_email_read_outlined)), Icons.mark_email_read_outlined)),
IconButton( IconButton(
@ -390,9 +422,10 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
PopupMenuButton<String>( PopupMenuButton<String>(
icon: const Icon(Icons.more_vert), icon: const Icon(Icons.more_vert),
itemBuilder: (BuildContext context) { itemBuilder: (BuildContext context) {
if (!bulkOptionsState) { if (selectedThreads.isEmpty) {
//why tf?
return <PopupMenuEntry<String>>[ return <PopupMenuEntry<String>>[
const PopupMenuItem<String>( PopupMenuItem<String>(
child: Row( child: Row(
children: [ children: [
Icon(Icons Icon(Icons
@ -403,19 +436,28 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
Text("Mark all as read") Text("Mark all as read")
], ],
), ),
onTap: () {
_emailPageKey.currentState!
.selectAllEmails(true);
_emailPageKey.currentState!
.markSelectedAsRead(true);
_emailPageKey.currentState!
.selectAllEmails(false);
},
), ),
const PopupMenuDivider(), const PopupMenuDivider(),
PopupMenuItem( PopupMenuItem(
child: Text( child: Text(
"Select messages to see more actions", "Select messages to see more actions",
style: TextStyle( style: TextStyle(
color: Colors color: Colors
.blueGrey.shade300), .blueGrey.shade300),
)) ),
)
]; ];
} else { } else {
return <PopupMenuEntry<String>>[ return <PopupMenuEntry<String>>[
const PopupMenuItem<String>( PopupMenuItem<String>(
child: Row( child: Row(
children: [ children: [
Icon(Icons Icon(Icons
@ -426,28 +468,34 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
Text("Mark as unread") Text("Mark as unread")
], ],
), ),
onTap: () {
_emailPageKey.currentState!
.markSelectedAsRead(
false);
},
), ),
const PopupMenuItem<String>( const PopupMenuItem<String>(
child: Row( child: Row(
children: [ children: [
Icon(Icons.snooze_outlined), Icon(Icons.snooze_outlined),
const SizedBox( const SizedBox(
width: 4.0, width: 4.0,
), ),
Text("Snooze") Text("Snooze")
], ],
), ),
), ),
const PopupMenuItem<String>( const PopupMenuItem<String>(
child: Row( child: Row(
children: [ children: [
Icon(Icons.star_border_outlined), Icon(Icons
const SizedBox( .star_border_outlined),
width: 4.0, const SizedBox(
), width: 4.0,
Text("Add star") ),
], Text("Add star")
), ],
),
), ),
]; ];
} }