HyM attachments resolve: #2 #3
@ -1,20 +1,29 @@
|
|||||||
// this file should handle most of the API calls
|
// this file should handle most of the API calls
|
||||||
// it also builds some widgets, but it will be modulated later
|
// it also builds some widgets, but it will be modulated later
|
||||||
|
|
||||||
import 'package:crab_ui/structs.dart';
|
import 'dart:async';
|
||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||||
|
|
||||||
|
import '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;
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui_web' as ui;
|
import 'dart:ui_web' as ui;
|
||||||
import 'augment.dart';
|
import 'augment.dart';
|
||||||
import 'dart:html' as html;
|
import 'dart:html' as html;
|
||||||
|
import 'dart:js' as js;
|
||||||
|
|
||||||
class ApiService {
|
class ApiService {
|
||||||
static String ip = "";
|
static String ip = "";
|
||||||
static String port = "";
|
static String port = "";
|
||||||
|
static List<AttachmentResponse> threadAttachments = [];
|
||||||
|
static String currFolder = "";
|
||||||
|
static List<String> currThread = [];
|
||||||
|
|
||||||
Future<List<GetThreadResponse>> fetchEmailsFromFolder(
|
Future<List<GetThreadResponse>> fetchEmailsFromFolder(
|
||||||
String folder, int pagenitaion) async {
|
String folder, int pagenitaion) async {
|
||||||
// print(ip + " " + port);
|
|
||||||
try {
|
try {
|
||||||
var url = Uri.http('$ip:$port', 'sorted_threads_by_date', {
|
var url = Uri.http('$ip:$port', 'sorted_threads_by_date', {
|
||||||
'folder': folder,
|
'folder': folder,
|
||||||
@ -51,8 +60,8 @@ class ApiService {
|
|||||||
int threadId,
|
int threadId,
|
||||||
List<GetThreadResponse> allEmails) async {
|
List<GetThreadResponse> allEmails) async {
|
||||||
try {
|
try {
|
||||||
var url =
|
var url = Uri.http('${ApiService.ip}:${ApiService.port}', 'get_thread',
|
||||||
Uri.http('$ip:$port', 'get_thread', {'id': threadId.toString()});
|
{'id': threadId.toString()});
|
||||||
var response = await http.get(url);
|
var response = await http.get(url);
|
||||||
|
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
@ -97,24 +106,34 @@ class ApiService {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> fetchEmailContent(List<String> IDs) async {
|
//returns the html for the email, it gets used in emailView
|
||||||
|
Future<String> fetchEmailContent(
|
||||||
|
List<String> IDsString, String emailFolder) async {
|
||||||
String content = r"""
|
String content = r"""
|
||||||
""";
|
""";
|
||||||
|
threadAttachments = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
//attaches email after email from a thread
|
//attaches email after email from a thread
|
||||||
for (var id in IDs) {
|
for (var id in IDsString) {
|
||||||
var url = Uri.http('$ip:$port', 'email', {'id': id});
|
var url = Uri.http('$ip:$port', 'email', {'id': id});
|
||||||
|
|
||||||
var response = await http.get(url);
|
var response = await http.get(url);
|
||||||
|
currThread.add(id);
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
content += response.body;
|
content += response.body;
|
||||||
try {
|
try {
|
||||||
getAttachmentsInfo("INBOX", id);
|
List<AttachmentInfo> attachments = await getAttachmentsInfo(
|
||||||
|
emailFolder, id);
|
||||||
|
for (var attachment in attachments) {
|
||||||
|
//TODO: for each attachment creaate at the bottom a widget for each individual one
|
||||||
|
threadAttachments
|
||||||
|
.add(await getAttachment(emailFolder, id, attachment.name));
|
||||||
|
}
|
||||||
} catch (innerError) {
|
} catch (innerError) {
|
||||||
print('_getAttachment info caught error $innerError');
|
print('_getAttachment info caught error $innerError');
|
||||||
}
|
}
|
||||||
|
content +=
|
||||||
|
"""<div id="JuanBedarramarker" style="width: 10px; height: 30px;"></div>""";
|
||||||
content += "<hr>";
|
content += "<hr>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,18 +219,21 @@ class ApiService {
|
|||||||
Future<List<AttachmentInfo>> getAttachmentsInfo(
|
Future<List<AttachmentInfo>> getAttachmentsInfo(
|
||||||
String folder, String email_id) async {
|
String folder, String email_id) async {
|
||||||
try {
|
try {
|
||||||
var url = Uri.http('127.0.0.1:3001', 'get_attachments_info',
|
var url = Uri.http('$ip:$port', 'get_attachments_info',
|
||||||
{'folder': folder, 'email_id': email_id});
|
{'folder': folder, 'id': email_id});
|
||||||
print(url);
|
// print(url);
|
||||||
var response = await http.get(url);
|
var response = await http.get(url);
|
||||||
print("response $response");
|
// print("response $response");
|
||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
var result = response.body;
|
var result = response.body;
|
||||||
|
// print(result);
|
||||||
List<dynamic> attachmentList = json.decode(result);
|
List<dynamic> attachmentList = json.decode(result);
|
||||||
print("attachment list $attachmentList");
|
// Map<String, dynamic> attachmentList = json.decode(result);
|
||||||
|
|
||||||
|
// print("attachment list $attachmentList");
|
||||||
List<AttachmentInfo> attachments =
|
List<AttachmentInfo> attachments =
|
||||||
attachmentList.map((al) => AttachmentInfo.fromJson(al)).toList();
|
attachmentList.map((al) => AttachmentInfo.fromJson(al)).toList();
|
||||||
print("attachments $attachments");
|
// print("attachments $attachments");
|
||||||
|
|
||||||
return attachments;
|
return attachments;
|
||||||
}
|
}
|
||||||
@ -220,6 +242,93 @@ class ApiService {
|
|||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<AttachmentResponse> getAttachment(
|
||||||
|
String folder, String email_id, String name) async {
|
||||||
|
try {
|
||||||
|
var url = Uri.http('$ip:$port', 'get_attachment',
|
||||||
|
{'folder': folder, 'id': email_id, 'name': name});
|
||||||
|
var response = await http.get(url);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
var result = response.body;
|
||||||
|
// print(result);
|
||||||
|
Map<String, dynamic> attachmentData = json.decode(result);
|
||||||
|
AttachmentResponse data = AttachmentResponse.fromJson(attachmentData);
|
||||||
|
print("data $data");
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
print("getAttachment failed $e");
|
||||||
|
}
|
||||||
|
return AttachmentResponse(name: "error", data: Uint8List(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<Map<String, dynamic>>> getMarkerPosition() async {
|
||||||
|
print("maerker called");
|
||||||
|
// JavaScript code embedded as a string
|
||||||
|
String jsCode = '''
|
||||||
|
(async function waitForIframeAndMarkers() {
|
||||||
|
try {
|
||||||
|
return await new Promise((resolve) => {
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
console.log("⏳ Checking for iframe...");
|
||||||
|
var iframe = document.getElementsByTagName('iframe')[0];
|
||||||
|
if (iframe && iframe.contentDocument) {
|
||||||
|
console.log("✅ Iframe found!");
|
||||||
|
var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
|
||||||
|
var markers = iframeDoc.querySelectorAll('[id^="JuanBedarramarker"]');
|
||||||
|
if (markers.length > 0) {
|
||||||
|
console.log(`✅ Found markers in the iframe.`);
|
||||||
|
var positions = [];
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
var rect = marker.getBoundingClientRect();
|
||||||
|
positions.push({
|
||||||
|
id: marker.id,
|
||||||
|
x: rect.left + window.scrollX,
|
||||||
|
y: rect.top + window.scrollY,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.log("📌 Marker positions:", positions);
|
||||||
|
clearInterval(interval);
|
||||||
|
resolve(JSON.stringify(positions)); // Ensure proper JSON string
|
||||||
|
} else {
|
||||||
|
console.log("❌ No markers found yet.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("❌ Iframe not found or not loaded yet.");
|
||||||
|
}
|
||||||
|
}, 200);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("JS Error:", error);
|
||||||
|
throw error; // Propagate error to Dart
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
''';
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Execute the JavaScript code using eval
|
||||||
|
final result = await js.context.callMethod('eval', [jsCode]);
|
||||||
|
|
||||||
|
if (result != null && result is String) {
|
||||||
|
print("Result received: $result");
|
||||||
|
|
||||||
|
// Parse the JSON string returned by JavaScript into a Dart list of maps
|
||||||
|
final List<dynamic> parsedResult = jsonDecode(result);
|
||||||
|
var positions = List<Map<String, dynamic>>.from(parsedResult);
|
||||||
|
print("positions put on");
|
||||||
|
print(positions);
|
||||||
|
return positions;
|
||||||
|
} else {
|
||||||
|
print("result is null or not a string");
|
||||||
|
}
|
||||||
|
} catch (e, stackTrace) {
|
||||||
|
print("Error executing JavaScript: $e");
|
||||||
|
print(stackTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EmailView extends StatefulWidget {
|
class EmailView extends StatefulWidget {
|
||||||
@ -246,10 +355,18 @@ class EmailView extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _EmailViewState extends State<EmailView> {
|
class _EmailViewState extends State<EmailView> {
|
||||||
|
//html css rendering thing
|
||||||
late Key iframeKey;
|
late Key iframeKey;
|
||||||
late String currentContent;
|
late String currentContent;
|
||||||
late String viewTypeId;
|
late String viewTypeId;
|
||||||
|
Future<List<Map<String, dynamic>>>? _markerPositionsFuture;
|
||||||
// TextEditingController _jumpController = TextEditingController();
|
// TextEditingController _jumpController = TextEditingController();
|
||||||
|
final hardcodedMarkers = [
|
||||||
|
{'id': 'marker1', 'x': 50, 'y': 100},
|
||||||
|
{'id': 'marker2', 'x': 150, 'y': 200},
|
||||||
|
{'id': 'marker3', 'x': 250, 'y': 300},
|
||||||
|
];
|
||||||
|
ApiService _apiService = ApiService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -257,6 +374,7 @@ class _EmailViewState extends State<EmailView> {
|
|||||||
String currentContent = widget.emailContent;
|
String currentContent = widget.emailContent;
|
||||||
viewTypeId = "iframe-${DateTime.now().millisecondsSinceEpoch}";
|
viewTypeId = "iframe-${DateTime.now().millisecondsSinceEpoch}";
|
||||||
_registerViewFactory(currentContent);
|
_registerViewFactory(currentContent);
|
||||||
|
_markerPositionsFuture = ApiService().getMarkerPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _registerViewFactory(String currentContent) {
|
void _registerViewFactory(String currentContent) {
|
||||||
@ -276,7 +394,7 @@ class _EmailViewState extends State<EmailView> {
|
|||||||
AugmentClasses.handleJump(spanId);
|
AugmentClasses.handleJump(spanId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: void _invisibility(String )
|
// TODO: void _invisibility(String ) //to make purple numbers not visible
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -285,7 +403,9 @@ class _EmailViewState extends State<EmailView> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(widget.name),
|
title: Text(widget.name),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Stack(
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
children: [
|
children: [
|
||||||
EmailToolbar(
|
EmailToolbar(
|
||||||
onJumpToSpan: _scrollToNumber,
|
onJumpToSpan: _scrollToNumber,
|
||||||
@ -309,8 +429,7 @@ class _EmailViewState extends State<EmailView> {
|
|||||||
// print("change");
|
// print("change");
|
||||||
// widget.emailContent = r"
|
// widget.emailContent = r"
|
||||||
|
|
||||||
// "
|
//
|
||||||
// },
|
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
// title of email
|
// title of email
|
||||||
@ -355,6 +474,71 @@ class _EmailViewState extends State<EmailView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
),
|
||||||
|
|
||||||
|
// Overlay widgets dynamically based on marker positions
|
||||||
|
FutureBuilder<List<Map<String, dynamic>>>(
|
||||||
|
future: _markerPositionsFuture,
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
print("FutureBuilder state: ${snapshot.connectionState}");
|
||||||
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
if (snapshot.hasError) {
|
||||||
|
print("Error in FutureBuilder: ${snapshot.error}");
|
||||||
|
return Center(child: Text('error loading markers'));
|
||||||
|
}
|
||||||
|
if (snapshot.hasData && snapshot.data != null) {
|
||||||
|
final markers = snapshot.data!;
|
||||||
|
return Stack(
|
||||||
|
children: markers.map((marker) {
|
||||||
|
return Positioned(
|
||||||
|
left: marker['x'].toDouble(),
|
||||||
|
top: marker['y'].toDouble(),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
print('Tapped on ${marker['id']}');
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
color: Colors.red,
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
marker['id'],
|
||||||
|
style: TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SizedBox.shrink(); // No markers found
|
||||||
|
},
|
||||||
|
),
|
||||||
|
// Red widget overlay
|
||||||
|
// Positioned(
|
||||||
|
// left: 8, // Adjust based on your desired position
|
||||||
|
// top: 100 + 44 + 5, // Adjust based on your desired position
|
||||||
|
// child: IgnorePointer(
|
||||||
|
// ignoring: true, // Ensures the iframe remains interactive
|
||||||
|
// child: Container(
|
||||||
|
// color: Colors.red,
|
||||||
|
// width: 100,
|
||||||
|
// height: 50,
|
||||||
|
// child: Center(
|
||||||
|
// child: Text(
|
||||||
|
// 'Overlay',
|
||||||
|
// style: TextStyle(color: Colors.white),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import 'package:crab_ui/api_service.dart';
|
||||||
|
import 'package:crab_ui/structs.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'dart:html' as html;
|
import 'dart:html' as html;
|
||||||
import 'dart:js' as js;
|
import 'dart:js' as js;
|
||||||
@ -64,8 +66,8 @@ class _DynamicClassesAugment extends State<EmailToolbar> {
|
|||||||
child: Text('Reload'),
|
child: Text('Reload'),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: AugmentClasses.handleImages,
|
onPressed: () => AugmentClasses.handleImages(context),
|
||||||
child: Text('Images'),
|
child: Text('Attachments'),
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
@ -206,6 +208,8 @@ class _DynamicClassesAugment extends State<EmailToolbar> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AugmentClasses {
|
class AugmentClasses {
|
||||||
|
ApiService _apiService = ApiService();
|
||||||
|
static OverlayEntry? _overlayEntry;
|
||||||
static void handleHome(BuildContext context) {
|
static void handleHome(BuildContext context) {
|
||||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||||
}
|
}
|
||||||
@ -214,8 +218,85 @@ class AugmentClasses {
|
|||||||
print("reload");
|
print("reload");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleImages() {
|
static void handleImages(BuildContext context) {
|
||||||
print("Images button pressed");
|
print("Images button pressed");
|
||||||
|
final overlay = Overlay.of(context);
|
||||||
|
final renderBox = context.findRenderObject() as RenderBox;
|
||||||
|
final offset = renderBox.localToGlobal(Offset.zero);
|
||||||
|
|
||||||
|
_overlayEntry = OverlayEntry(
|
||||||
|
builder: (context) => Stack(
|
||||||
|
children: [
|
||||||
|
// Dimmed background
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () => _overlayEntry?.remove(),
|
||||||
|
child: Container(
|
||||||
|
color: Colors.black54,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.height,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
// Focused content window
|
||||||
|
Center(
|
||||||
|
child: Positioned(
|
||||||
|
left: offset.dx + 500,
|
||||||
|
top: offset.dy + renderBox.size.height + 100,
|
||||||
|
child: Material(
|
||||||
|
elevation: 8,
|
||||||
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 400,
|
||||||
|
maxHeight: 500,
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
_buildHeader(),
|
||||||
|
const Divider(height: 1),
|
||||||
|
Expanded(
|
||||||
|
child: ListView(
|
||||||
|
children: _buildMenuItem(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
if (_overlayEntry != null) {
|
||||||
|
overlay.insert(_overlayEntry!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add missing widget builder methods
|
||||||
|
static Widget _buildHeader() {
|
||||||
|
return const Padding(
|
||||||
|
padding: EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
'Thread Attachments',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<Widget> _buildMenuItem() {
|
||||||
|
List<Widget> listOfFiles = [];
|
||||||
|
for (AttachmentResponse file in ApiService.threadAttachments) {
|
||||||
|
listOfFiles.add(ListTile(
|
||||||
|
leading: Icon(Icons.file_present),
|
||||||
|
title: Text(file.name.toString()),
|
||||||
|
onTap: () {
|
||||||
|
_overlayEntry?.remove();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return listOfFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleOpen() {
|
static void handleOpen() {
|
||||||
@ -517,6 +598,7 @@ class AugmentClasses {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void disableIframePointerEvents() {
|
static void disableIframePointerEvents() {
|
||||||
|
//pretty sure these dont work
|
||||||
final iframes = html.document.getElementsByTagName('iframe');
|
final iframes = html.document.getElementsByTagName('iframe');
|
||||||
for (var iframe in iframes) {
|
for (var iframe in iframes) {
|
||||||
if (iframe is html.Element) {
|
if (iframe is html.Element) {
|
||||||
|
@ -4,10 +4,12 @@ import 'structs.dart';
|
|||||||
|
|
||||||
class EmailListScreen extends StatelessWidget {
|
class EmailListScreen extends StatelessWidget {
|
||||||
final List<GetThreadResponse> emails;
|
final List<GetThreadResponse> emails;
|
||||||
final Future<String> Function(List<String>) getEmailContent;
|
final Future<String> Function(List<String>, String) getEmailContent;
|
||||||
|
final String folder;
|
||||||
|
|
||||||
EmailListScreen({required this.emails, required this.getEmailContent});
|
|
||||||
|
|
||||||
|
EmailListScreen({required this.emails, required this.getEmailContent, required this.folder});
|
||||||
|
//fix the email list
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -24,7 +26,7 @@ class EmailListScreen extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
trailing: Text(email.date.toString()),
|
trailing: Text(email.date.toString()),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
String emailContent = await getEmailContent(email.messages);
|
String emailContent = await getEmailContent(email.messages, folder);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@ -51,7 +53,7 @@ class EmailListScreen extends StatelessWidget {
|
|||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class EmailPage extends StatefulWidget {
|
class EmailPage extends StatefulWidget {
|
||||||
EmailPage({Key? key}) : super(key: key);
|
EmailPage({Key? key}) : super(key: key);
|
||||||
String selectedFolder = "INBOX";
|
String selectedFolder = "INBOX"; //starter
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int page = 1;
|
int page = 1;
|
||||||
|
|
||||||
@ -62,11 +64,14 @@ class EmailPage extends StatefulWidget {
|
|||||||
class EmailPageState extends State<EmailPage> {
|
class EmailPageState extends State<EmailPage> {
|
||||||
final ApiService apiService = ApiService();
|
final ApiService apiService = ApiService();
|
||||||
List<GetThreadResponse> emails = [];
|
List<GetThreadResponse> emails = [];
|
||||||
|
int page = 1;
|
||||||
|
bool isBackDisabled = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
widget.page = widget.page;
|
widget.page = page;
|
||||||
|
isBackDisabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSelectedFolder(String folder) {
|
void updateSelectedFolder(String folder) {
|
||||||
@ -86,11 +91,16 @@ class EmailPageState extends State<EmailPage> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
widget.offset += 50;
|
widget.offset += 50;
|
||||||
widget.page += 1;
|
widget.page += 1;
|
||||||
|
isBackDisabled = false;
|
||||||
});
|
});
|
||||||
} else if (option == "back") {
|
} else if (option == "back") {
|
||||||
setState(() {
|
setState(() {
|
||||||
widget.offset -= 50;
|
widget.offset -= 50;
|
||||||
widget.page -= 1;
|
widget.page -= 1;
|
||||||
|
if (widget.page == 1) {
|
||||||
|
isBackDisabled = true;
|
||||||
|
print("back dis");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// print(currentPage);
|
// print(currentPage);
|
||||||
@ -119,6 +129,7 @@ class EmailPageState extends State<EmailPage> {
|
|||||||
body: EmailListScreen(
|
body: EmailListScreen(
|
||||||
emails: emails,
|
emails: emails,
|
||||||
getEmailContent: apiService.fetchEmailContent,
|
getEmailContent: apiService.fetchEmailContent,
|
||||||
|
folder: widget.selectedFolder,//try to grab from it directly
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import 'package:crab_ui/folder_drawer.dart';
|
import 'folder_drawer.dart';
|
||||||
import 'package:crab_ui/structs.dart';
|
import 'structs.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'api_service.dart';
|
import 'api_service.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'email.dart';
|
import 'email.dart';
|
||||||
|
// import 'package:shared_preferences/shared_preferences.dart';
|
||||||
// import 'serialize.dart';
|
// import 'serialize.dart';
|
||||||
|
|
||||||
class HomeScreen extends StatefulWidget {
|
class HomeScreen extends StatefulWidget {
|
||||||
@ -119,7 +120,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
|||||||
body: ListView.separated(
|
body: ListView.separated(
|
||||||
itemCount: result.length,
|
itemCount: result.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final email = result[index];
|
final SerializableMessage email = result[index];
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(email.from,
|
title: Text(email.from,
|
||||||
style: TextStyle(fontWeight: FontWeight.bold)),
|
style: TextStyle(fontWeight: FontWeight.bold)),
|
||||||
@ -131,7 +132,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
|||||||
onTap: () async {
|
onTap: () async {
|
||||||
// print('tapped');
|
// print('tapped');
|
||||||
String emailContent =
|
String emailContent =
|
||||||
await apiService.fetchEmailContent([email.id]);
|
await apiService.fetchEmailContent([email.id], email.list);
|
||||||
// print('content below');
|
// print('content below');
|
||||||
// print(emailContent);
|
// print(emailContent);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
@ -341,7 +342,7 @@ class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
|
|||||||
children: [
|
children: [
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_emailPageKey.currentState
|
_emailPageKey.currentState!.isBackDisabled ? null: _emailPageKey.currentState
|
||||||
?.updatePagenation('back');
|
?.updatePagenation('back');
|
||||||
},
|
},
|
||||||
child: Icon(Icons.navigate_before),
|
child: Icon(Icons.navigate_before),
|
||||||
|
@ -18,6 +18,7 @@ dependencies:
|
|||||||
encrypt: ^5.0.0
|
encrypt: ^5.0.0
|
||||||
pointycastle: ^3.4.0
|
pointycastle: ^3.4.0
|
||||||
mime: ^1.0.3
|
mime: ^1.0.3
|
||||||
|
pointer_interceptor: ^0.10.1+2
|
||||||
|
|
||||||
english_words: ^4.0.0
|
english_words: ^4.0.0
|
||||||
provider: ^6.0.0
|
provider: ^6.0.0
|
||||||
|
Loading…
Reference in New Issue
Block a user