commit
						10f95941d4
					
				
					 5 changed files with 427 additions and 117 deletions
				
			
		| 
						 | 
				
			
			@ -10,10 +10,13 @@ import 'augment.dart';
 | 
			
		|||
import 'dart:html' as html;
 | 
			
		||||
 | 
			
		||||
class ApiService {
 | 
			
		||||
  static String ip = "";
 | 
			
		||||
  static String port = "";
 | 
			
		||||
  Future<List<GetThreadResponse>> fetchEmailsFromFolder(
 | 
			
		||||
      String folder, int pagenitaion) async {
 | 
			
		||||
    // print(ip + " " + port);
 | 
			
		||||
    try {
 | 
			
		||||
      var url = Uri.http('127.0.0.1:3001', 'sorted_threads_by_date', {
 | 
			
		||||
      var url = Uri.http('$ip:$port', 'sorted_threads_by_date', {
 | 
			
		||||
        'folder': folder,
 | 
			
		||||
        'limit': '50',
 | 
			
		||||
        'offset': pagenitaion.toString(),
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +52,7 @@ class ApiService {
 | 
			
		|||
      List<GetThreadResponse> allEmails) async {
 | 
			
		||||
    try {
 | 
			
		||||
      var url =
 | 
			
		||||
          Uri.http('127.0.0.1:3001', 'get_thread', {'id': threadId.toString()});
 | 
			
		||||
          Uri.http('$ip:$port', 'get_thread', {'id': threadId.toString()});
 | 
			
		||||
      var response = await http.get(url);
 | 
			
		||||
 | 
			
		||||
      if (response.statusCode == 200) {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,15 +73,16 @@ class ApiService {
 | 
			
		|||
  Future<List<SerializableMessage>> sonicSearch(
 | 
			
		||||
      String list, int limit, int offset, String query) async {
 | 
			
		||||
    try {
 | 
			
		||||
      var url = Uri.http('127.0.0.1:3001', 'search', {
 | 
			
		||||
      var url = Uri.http('$ip:$port', 'search_emails', {
 | 
			
		||||
        'list': list,
 | 
			
		||||
        'limit': limit.toString(),
 | 
			
		||||
        'offset': offset.toString(),
 | 
			
		||||
        'query': query
 | 
			
		||||
      });
 | 
			
		||||
      print(url);
 | 
			
		||||
 | 
			
		||||
      var response = await http.get(url);
 | 
			
		||||
 | 
			
		||||
      print(response);
 | 
			
		||||
      if (response.statusCode == 200) {
 | 
			
		||||
        List<dynamic> messagesJson = json.decode(response.body);
 | 
			
		||||
        List<SerializableMessage> messages =
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +90,7 @@ class ApiService {
 | 
			
		|||
 | 
			
		||||
        return messages;
 | 
			
		||||
      }
 | 
			
		||||
      print(response.statusCode);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print("caught $e");
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -99,12 +104,17 @@ class ApiService {
 | 
			
		|||
    try {
 | 
			
		||||
      //attaches email after email from a thread
 | 
			
		||||
      for (var id in IDs) {
 | 
			
		||||
        var url = Uri.http('127.0.0.1:3001', 'email', {'id': id});
 | 
			
		||||
        var url = Uri.http('$ip:$port', 'email', {'id': id});
 | 
			
		||||
 | 
			
		||||
        var response = await http.get(url);
 | 
			
		||||
 | 
			
		||||
        if (response.statusCode == 200) {
 | 
			
		||||
          content += response.body;
 | 
			
		||||
          try {
 | 
			
		||||
            getAttachmentsInfo("INBOX", id);
 | 
			
		||||
          } catch (innerError) {
 | 
			
		||||
            print('_getAttachment info caught error $innerError');
 | 
			
		||||
          }
 | 
			
		||||
          content += "<hr>";
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +131,7 @@ class ApiService {
 | 
			
		|||
 | 
			
		||||
  Future<List<String>> fetchFolders() async {
 | 
			
		||||
    try {
 | 
			
		||||
      var url = Uri.http('127.0.0.1:3001', 'folders');
 | 
			
		||||
      var url = Uri.http('$ip:$port', 'folders');
 | 
			
		||||
      var response = await http.get(url);
 | 
			
		||||
      return List<String>.from(json.decode(response.body));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +141,7 @@ class ApiService {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> createFolder(String folderName) async {
 | 
			
		||||
    var url = Uri.http('127.0.0.1:3001', 'create_folder');
 | 
			
		||||
    var url = Uri.http('$ip:$port', 'create_folder');
 | 
			
		||||
 | 
			
		||||
    Map<String, String> requestBody = {'name': folderName};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +164,7 @@ class ApiService {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> deleteFolder(String folderName) async {
 | 
			
		||||
    var url = Uri.http('127.0.0.1:3001', 'delete_folder');
 | 
			
		||||
    var url = Uri.http('$ip:$port', 'delete_folder');
 | 
			
		||||
 | 
			
		||||
    Map<String, String> requestBody = {'name': folderName};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -175,6 +185,41 @@ class ApiService {
 | 
			
		|||
      print('error making post req: $e');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> logIn(String json) async {
 | 
			
		||||
    // var url = Uri.https('')
 | 
			
		||||
    // try{
 | 
			
		||||
    //   String response = await http.post(
 | 
			
		||||
    //     url
 | 
			
		||||
    //     );
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<List<AttachmentInfo>> getAttachmentsInfo(
 | 
			
		||||
      String folder, String email_id) async {
 | 
			
		||||
    try {
 | 
			
		||||
      var url = Uri.http('127.0.0.1:3001', 'get_attachments_info',
 | 
			
		||||
          {'folder': folder, 'email_id': email_id});
 | 
			
		||||
      print(url);
 | 
			
		||||
      var response = await http.get(url);
 | 
			
		||||
      print("response $response");
 | 
			
		||||
      if (response.statusCode == 200) {
 | 
			
		||||
        var result = response.body;
 | 
			
		||||
        List<dynamic> attachmentList = json.decode(result);
 | 
			
		||||
        print("attachment list $attachmentList");
 | 
			
		||||
        List<AttachmentInfo> attachments =
 | 
			
		||||
            attachmentList.map((al) => AttachmentInfo.fromJson(al)).toList();
 | 
			
		||||
        print("attachments $attachments");
 | 
			
		||||
 | 
			
		||||
        return attachments;
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print(e);
 | 
			
		||||
    }
 | 
			
		||||
    return [];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class EmailView extends StatefulWidget {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										444
									
								
								lib/login.dart
									
										
									
									
									
								
							
							
						
						
									
										444
									
								
								lib/login.dart
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,24 +1,72 @@
 | 
			
		|||
import 'dart:convert';
 | 
			
		||||
import 'package:crab_ui/api_service.dart';
 | 
			
		||||
import 'package:crab_ui/home_page.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
// import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
 | 
			
		||||
import 'package:http/http.dart' as http;
 | 
			
		||||
// import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
import 'package:flutter/services.dart' show rootBundle;
 | 
			
		||||
 | 
			
		||||
class AuthService {
 | 
			
		||||
  Future<bool> isUserLoggedIn() async {
 | 
			
		||||
    try {
 | 
			
		||||
      var url = Uri.http('127.0.0.1:3001', 'is_logged_in');
 | 
			
		||||
      var response = await http.get(url);
 | 
			
		||||
      final response =
 | 
			
		||||
          await http.get(Uri.parse('http://localhost:6823/read-config'));
 | 
			
		||||
      print(response.statusCode);
 | 
			
		||||
      print(response.body);
 | 
			
		||||
      if (response.statusCode == 200) {
 | 
			
		||||
        print('all good in the east!');
 | 
			
		||||
        List json = jsonDecode(response.body);
 | 
			
		||||
        print(json[0]);
 | 
			
		||||
        return true;
 | 
			
		||||
        final data = jsonDecode(response.body);
 | 
			
		||||
        // return data['config'];
 | 
			
		||||
        try {
 | 
			
		||||
          var url = Uri.http('${data['ip']}:${data['port']}', 'is_logged_in');
 | 
			
		||||
          var response = await http.get(url);
 | 
			
		||||
          print(response.body);
 | 
			
		||||
          if (response.statusCode == 200) {
 | 
			
		||||
            print('all good in the east!');
 | 
			
		||||
            String jsonOuter = jsonDecode(response.body);
 | 
			
		||||
            Map<String, dynamic> json = jsonDecode(jsonOuter);
 | 
			
		||||
            // print(json["is_logged_in"]);
 | 
			
		||||
            ApiService.ip = data['ip'];
 | 
			
		||||
            ApiService.port = data['port'];
 | 
			
		||||
            return json["is_logged_in"];
 | 
			
		||||
          }
 | 
			
		||||
        } catch (er) {
 | 
			
		||||
          print(er);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print(e);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<String> readConfFile() async {
 | 
			
		||||
    final content = await rootBundle.loadString('/crabmail.conf');
 | 
			
		||||
    return content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Map<String, String> parseConfFile(String content) {
 | 
			
		||||
    final Map<String, String> config = {};
 | 
			
		||||
    final lines = content.split('\n');
 | 
			
		||||
 | 
			
		||||
    for (var line in lines) {
 | 
			
		||||
      line = line.trim();
 | 
			
		||||
      if (line.isEmpty || line.startsWith('#')) continue;
 | 
			
		||||
 | 
			
		||||
      final parts = line.split('=');
 | 
			
		||||
      if (parts.length == 2) {
 | 
			
		||||
        final key = parts[0].trim();
 | 
			
		||||
        final value = parts[1].trim();
 | 
			
		||||
        config[key] = value;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return config;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> loginUser(String email, String password) async {
 | 
			
		||||
    try {} catch (e) {}
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class LoginPage extends StatefulWidget {
 | 
			
		||||
| 
						 | 
				
			
			@ -28,129 +76,327 @@ class LoginPage extends StatefulWidget {
 | 
			
		|||
  _LoginPageState createState() => _LoginPageState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class SplashScreen extends StatefulWidget {
 | 
			
		||||
  @override
 | 
			
		||||
  _SplashScreenState createState() => _SplashScreenState();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _SplashScreenState extends State<SplashScreen> {
 | 
			
		||||
  final AuthService _authService = AuthService();
 | 
			
		||||
  @override
 | 
			
		||||
  void initState() {
 | 
			
		||||
    super.initState();
 | 
			
		||||
    _checkLoginStatus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> _checkLoginStatus() async {
 | 
			
		||||
    // SharedPreferences prefs = await SharedPreferences.getInstance();
 | 
			
		||||
    // print(prefs);
 | 
			
		||||
    // bool isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
 | 
			
		||||
    bool isLoggedIn = await _authService.isUserLoggedIn();
 | 
			
		||||
    print("is loogeed in $isLoggedIn");
 | 
			
		||||
    if (isLoggedIn) {
 | 
			
		||||
      Navigator.pushReplacementNamed(context, '/home');
 | 
			
		||||
    } else {
 | 
			
		||||
      Navigator.pushReplacementNamed(context, '/login');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
        body: Center(child: CircularProgressIndicator()),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class _LoginPageState extends State<LoginPage> {
 | 
			
		||||
  final AuthService _authService = AuthService();
 | 
			
		||||
  // Controllers for capturing user input
 | 
			
		||||
  final TextEditingController _ipController = TextEditingController();
 | 
			
		||||
  final TextEditingController _portController = TextEditingController();
 | 
			
		||||
  final TextEditingController _emailController = TextEditingController();
 | 
			
		||||
  final TextEditingController _passwordController = TextEditingController();
 | 
			
		||||
 | 
			
		||||
  // final ConfigManager _configManager =
 | 
			
		||||
  //     ConfigManager("${Directory.current.parent}../crabmail2.conf");
 | 
			
		||||
  // Key to identify the form
 | 
			
		||||
  final _formKey = GlobalKey<FormState>();
 | 
			
		||||
 | 
			
		||||
  void checkLogin() async {
 | 
			
		||||
    // try {
 | 
			
		||||
    //   var url = Uri.http('127.0.0.1:3001', 'is_logged_in');
 | 
			
		||||
    //   var response = await http.get(url);
 | 
			
		||||
    //   print(response.body);
 | 
			
		||||
    //   if (response.statusCode == 200) {
 | 
			
		||||
    //     print('all good on the west');
 | 
			
		||||
    //   }
 | 
			
		||||
    // } catch (e) {
 | 
			
		||||
    //   print(e);
 | 
			
		||||
    // }
 | 
			
		||||
    bool isLoggedIn = await _authService.isUserLoggedIn();
 | 
			
		||||
    
 | 
			
		||||
  Future<bool> setIp(String ip) async {
 | 
			
		||||
    // _configManager.setField("api_addr", ip);
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> setPort(String port) async {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<void> login() async {
 | 
			
		||||
    bool result = await _handleLogin();
 | 
			
		||||
    if (result) {
 | 
			
		||||
      Navigator.pushReplacementNamed(context, '/home');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // Future<bool> _checkConfiguration() async {
 | 
			
		||||
  //   return false;
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // void checkLogin() async {
 | 
			
		||||
  //   try {
 | 
			
		||||
  //     var url = Uri.http('127.0.0.1:3001', 'is_logged_in');
 | 
			
		||||
  //     var response = await http.get(url);
 | 
			
		||||
  //     print(response.body);
 | 
			
		||||
  //     if (response.statusCode == 200) {
 | 
			
		||||
  //       print('all good on the west');
 | 
			
		||||
  //     }
 | 
			
		||||
  //   } catch (e) {
 | 
			
		||||
  //     print(e);
 | 
			
		||||
  //   }
 | 
			
		||||
  //   // bool isLoggedIn = await _authService.isUserLoggedIn();
 | 
			
		||||
  // }
 | 
			
		||||
 | 
			
		||||
  // Function to handle login action
 | 
			
		||||
  void _handleLogin() {
 | 
			
		||||
  Future<bool> _handleLogin() async {
 | 
			
		||||
    if (_formKey.currentState!.validate()) {
 | 
			
		||||
      // Perform login action (e.g., authenticate with backend)
 | 
			
		||||
      String ip = _ipController.text;
 | 
			
		||||
      String port = _portController.text;
 | 
			
		||||
      String email = _emailController.text;
 | 
			
		||||
      String password = _passwordController.text;
 | 
			
		||||
 | 
			
		||||
      // For demonstration, just print the values
 | 
			
		||||
      print('Email: $email');
 | 
			
		||||
      print('Password: $password');
 | 
			
		||||
      print(ip);
 | 
			
		||||
      print(port);
 | 
			
		||||
 | 
			
		||||
      String baseUrl = "http://$ip:$port";
 | 
			
		||||
      print("baseurl " + baseUrl);
 | 
			
		||||
      print(baseUrl);
 | 
			
		||||
      try {
 | 
			
		||||
        final response =
 | 
			
		||||
            await http.get(Uri.parse('http://localhost:6823/read-config'));
 | 
			
		||||
        print(response.statusCode);
 | 
			
		||||
        print(response.body);
 | 
			
		||||
        if (response.statusCode == 200) {
 | 
			
		||||
          final data = jsonDecode(response.body);
 | 
			
		||||
          // return data['config'];
 | 
			
		||||
        }
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        print("caught in catch");
 | 
			
		||||
        print(e);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      Map<String, dynamic> updates = {
 | 
			
		||||
        // "username": email,
 | 
			
		||||
        // "password": password,
 | 
			
		||||
        "ip": ip,
 | 
			
		||||
        "port": port,
 | 
			
		||||
      };
 | 
			
		||||
      print("past");
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        final sending = await http.post(
 | 
			
		||||
            Uri.parse('http://localhost:6823/update-config'),
 | 
			
		||||
            headers: {'Content-Type': "application/json"},
 | 
			
		||||
            body: jsonEncode(updates));
 | 
			
		||||
        print("sending");
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        print(e);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      try {
 | 
			
		||||
        // String status = await http.post(Uri.parse(''))
 | 
			
		||||
        var url_log = Uri.http('$ip:$port', 'log_in');
 | 
			
		||||
        Map<String, dynamic> filteredData = {
 | 
			
		||||
          "email": email,
 | 
			
		||||
          "password": password,
 | 
			
		||||
          // 'email': updates['username'],
 | 
			
		||||
          // 'password': updates['password']
 | 
			
		||||
        };
 | 
			
		||||
        print(filteredData);
 | 
			
		||||
        var status = await http.post(
 | 
			
		||||
          url_log,
 | 
			
		||||
          headers: {
 | 
			
		||||
            'Content-Type': 'application/json',
 | 
			
		||||
          },
 | 
			
		||||
          body: jsonEncode(filteredData),
 | 
			
		||||
        );
 | 
			
		||||
        if (status.statusCode == 200) {
 | 
			
		||||
          print('response status ${status.body}');
 | 
			
		||||
          if (status.body == "Successful log in") {
 | 
			
		||||
            ApiService.ip = ip;
 | 
			
		||||
            ApiService.port = port;
 | 
			
		||||
            return true;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        print(e);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      print("after");
 | 
			
		||||
      return false;
 | 
			
		||||
      // final content = await _authService.readConfFile();
 | 
			
		||||
      // final config = await _authService.parseConfFile(content);
 | 
			
		||||
      // print("BASE URL ${config["base_url"]}");
 | 
			
		||||
      // print("api address ${config["api_addr"]}");
 | 
			
		||||
      // print(config);
 | 
			
		||||
      // const url = ''
 | 
			
		||||
      // Clear the input fields
 | 
			
		||||
      _emailController.clear();
 | 
			
		||||
      _passwordController.clear();
 | 
			
		||||
      // _ipController.clear();
 | 
			
		||||
      // _portController.clear();
 | 
			
		||||
      // _emailController.clear();
 | 
			
		||||
      // _passwordController.clear();
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  Widget build(BuildContext context) {
 | 
			
		||||
    return Scaffold(
 | 
			
		||||
      appBar: AppBar(
 | 
			
		||||
        title: const Text('Login Page'),
 | 
			
		||||
      ),
 | 
			
		||||
      body: Padding(
 | 
			
		||||
        padding: const EdgeInsets.all(16.0),
 | 
			
		||||
        child: Form(
 | 
			
		||||
          key: _formKey,
 | 
			
		||||
          child: Align(
 | 
			
		||||
            alignment: Alignment.centerLeft,
 | 
			
		||||
            child: Column(
 | 
			
		||||
              mainAxisSize: MainAxisSize.min,
 | 
			
		||||
              crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
              children: [
 | 
			
		||||
                Text('Sign in to your email'),
 | 
			
		||||
                SizedBox(
 | 
			
		||||
                  height: 5,
 | 
			
		||||
                ),
 | 
			
		||||
                // Email Field
 | 
			
		||||
                Container(
 | 
			
		||||
                  width: 200,
 | 
			
		||||
                  child: TextFormField(
 | 
			
		||||
                    controller: _emailController,
 | 
			
		||||
                    decoration: const InputDecoration(
 | 
			
		||||
                      labelText: 'Email',
 | 
			
		||||
                      hintText: 'Enter your email',
 | 
			
		||||
                      helperMaxLines: 1,
 | 
			
		||||
    // try {
 | 
			
		||||
    //   _configManager.loadConfig();
 | 
			
		||||
    //   print(_configManager.getField('base_url'));
 | 
			
		||||
    // } catch (e) {
 | 
			
		||||
    //   print("broke at build $e");
 | 
			
		||||
    // }
 | 
			
		||||
    // _configManager.
 | 
			
		||||
    return Center(
 | 
			
		||||
      child: Scaffold(
 | 
			
		||||
        appBar: AppBar(
 | 
			
		||||
          title: const Text('Login Page'),
 | 
			
		||||
        ),
 | 
			
		||||
        body: Center(
 | 
			
		||||
          child: SingleChildScrollView(
 | 
			
		||||
            padding: const EdgeInsets.all(16.0),
 | 
			
		||||
            child: Form(
 | 
			
		||||
              key: _formKey,
 | 
			
		||||
              child: Align(
 | 
			
		||||
                alignment: Alignment.center,
 | 
			
		||||
                child: Column(
 | 
			
		||||
                  mainAxisSize: MainAxisSize.min,
 | 
			
		||||
                  crossAxisAlignment: CrossAxisAlignment.start,
 | 
			
		||||
                  children: [
 | 
			
		||||
                    Text('Sign in to your email'),
 | 
			
		||||
                    SizedBox(
 | 
			
		||||
                      height: 5,
 | 
			
		||||
                    ),
 | 
			
		||||
                    validator: (value) {
 | 
			
		||||
                      // Simple email validation
 | 
			
		||||
                      if (value == null || value.isEmpty) {
 | 
			
		||||
                        return 'Please enter your email';
 | 
			
		||||
                      }
 | 
			
		||||
                      if (!RegExp(r'^\S+@\S+\.\S+$').hasMatch(value)) {
 | 
			
		||||
                        return 'Please enter a valid email address';
 | 
			
		||||
                      }
 | 
			
		||||
                      return null;
 | 
			
		||||
                    },
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(height: 16.0),
 | 
			
		||||
                // Password Field
 | 
			
		||||
                Container(
 | 
			
		||||
                  width: 200,
 | 
			
		||||
                  child: TextFormField(
 | 
			
		||||
                    controller: _passwordController,
 | 
			
		||||
                    decoration: const InputDecoration(
 | 
			
		||||
                      labelText: 'Password',
 | 
			
		||||
                      hintText: 'Enter your password',
 | 
			
		||||
                    Container(
 | 
			
		||||
                      width: 200,
 | 
			
		||||
                      child: TextFormField(
 | 
			
		||||
                        controller: _ipController,
 | 
			
		||||
                        decoration: const InputDecoration(
 | 
			
		||||
                          labelText: "IP",
 | 
			
		||||
                          hintText: 'Enter your IP for the backend',
 | 
			
		||||
                          helperMaxLines: 1,
 | 
			
		||||
                        ),
 | 
			
		||||
                        validator: (value) {
 | 
			
		||||
                          if (value == null || value.isEmpty) {
 | 
			
		||||
                            return 'Please enter your ip';
 | 
			
		||||
                          }
 | 
			
		||||
                        },
 | 
			
		||||
                        // onSaved: (value) async {
 | 
			
		||||
                        //   final content = await _authService.readConfFile();
 | 
			
		||||
                        //   final config =
 | 
			
		||||
                        //       await _authService.parseConfFile(content);
 | 
			
		||||
                        //   print("BASE URL ${config["base_url"]}");
 | 
			
		||||
                        //   print("api address ${config["api_addr"]}");
 | 
			
		||||
                        //   //TODO: call a function to set the field ip in conf
 | 
			
		||||
                        // },
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    obscureText: true, // Hide the password text
 | 
			
		||||
                    validator: (value) {
 | 
			
		||||
                      // Simple password validation
 | 
			
		||||
                      if (value == null || value.isEmpty) {
 | 
			
		||||
                        return 'Please enter your password';
 | 
			
		||||
                      }
 | 
			
		||||
                      if (value.length < 6) {
 | 
			
		||||
                        return 'Password must be at least 6 characters long';
 | 
			
		||||
                      }
 | 
			
		||||
                      return null;
 | 
			
		||||
                    },
 | 
			
		||||
                  ),
 | 
			
		||||
                    Container(
 | 
			
		||||
                      width: 200,
 | 
			
		||||
                      child: TextFormField(
 | 
			
		||||
                        controller: _portController,
 | 
			
		||||
                        decoration: const InputDecoration(
 | 
			
		||||
                          labelText: "Port",
 | 
			
		||||
                          hintText: 'Enter the port',
 | 
			
		||||
                          helperMaxLines: 1,
 | 
			
		||||
                        ),
 | 
			
		||||
                        validator: (value) {
 | 
			
		||||
                          if (value == null || value.isEmpty) {
 | 
			
		||||
                            return 'Please enter your port';
 | 
			
		||||
                          }
 | 
			
		||||
                          return null;
 | 
			
		||||
                        },
 | 
			
		||||
                        onSaved: (value) {
 | 
			
		||||
                          //TODO: call a function to set the field port in conf
 | 
			
		||||
                        },
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    // Email Field
 | 
			
		||||
                    Container(
 | 
			
		||||
                      width: 200,
 | 
			
		||||
                      child: TextFormField(
 | 
			
		||||
                        controller: _emailController,
 | 
			
		||||
                        decoration: const InputDecoration(
 | 
			
		||||
                          labelText: 'Email',
 | 
			
		||||
                          hintText: 'Enter your email',
 | 
			
		||||
                          helperMaxLines: 1,
 | 
			
		||||
                        ),
 | 
			
		||||
                        validator: (value) {
 | 
			
		||||
                          // Simple email validation
 | 
			
		||||
                          if (value == null || value.isEmpty) {
 | 
			
		||||
                            return 'Please enter your email';
 | 
			
		||||
                          }
 | 
			
		||||
                          if (!RegExp(r'^\S+@\S+\.\S+$').hasMatch(value)) {
 | 
			
		||||
                            // print(value);
 | 
			
		||||
                            return 'Please enter a valid email address';
 | 
			
		||||
                          }
 | 
			
		||||
                          return null;
 | 
			
		||||
                        },
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    const SizedBox(height: 16.0),
 | 
			
		||||
                    // Password Field
 | 
			
		||||
                    Container(
 | 
			
		||||
                      width: 200,
 | 
			
		||||
                      child: TextFormField(
 | 
			
		||||
                        controller: _passwordController,
 | 
			
		||||
                        decoration: const InputDecoration(
 | 
			
		||||
                          labelText: 'Password',
 | 
			
		||||
                          hintText: 'Enter your password',
 | 
			
		||||
                        ),
 | 
			
		||||
                        obscureText: true, // Hide the password text
 | 
			
		||||
                        autofillHints: null,
 | 
			
		||||
                        validator: (value) {
 | 
			
		||||
                          // Simple password validation
 | 
			
		||||
                          if (value == null || value.isEmpty) {
 | 
			
		||||
                            return 'Please enter your password';
 | 
			
		||||
                          }
 | 
			
		||||
                          if (value.length < 6) {
 | 
			
		||||
                            return 'Password must be at least 6 characters long';
 | 
			
		||||
                          }
 | 
			
		||||
                          return null;
 | 
			
		||||
                        },
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    const SizedBox(height: 32.0),
 | 
			
		||||
                    // Login Button
 | 
			
		||||
                    SizedBox(
 | 
			
		||||
                      width: 200,
 | 
			
		||||
                      child: ElevatedButton(
 | 
			
		||||
                        onPressed: login,
 | 
			
		||||
                        child: const Text('Login'),
 | 
			
		||||
                      ),
 | 
			
		||||
                    ),
 | 
			
		||||
                    // SizedBox(
 | 
			
		||||
                    //   width: 200,
 | 
			
		||||
                    //   child: ElevatedButton(
 | 
			
		||||
                    //     // onPressed: checkLogin,
 | 
			
		||||
                    //     onPressed: () async {
 | 
			
		||||
                    //       await _authService.isUserLoggedIn();
 | 
			
		||||
                    //       // print(result);
 | 
			
		||||
                    //     },
 | 
			
		||||
                    //     child: const Text('checker'),
 | 
			
		||||
                    //   ),
 | 
			
		||||
                    // )
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
                const SizedBox(height: 32.0),
 | 
			
		||||
                // Login Button
 | 
			
		||||
                SizedBox(
 | 
			
		||||
                  width: 200,
 | 
			
		||||
                  child: ElevatedButton(
 | 
			
		||||
                    onPressed: _handleLogin,
 | 
			
		||||
                    child: const Text('Login'),
 | 
			
		||||
                  ),
 | 
			
		||||
                ),
 | 
			
		||||
                SizedBox(
 | 
			
		||||
                  width: 200,
 | 
			
		||||
                  child: ElevatedButton(
 | 
			
		||||
                    onPressed: checkLogin,
 | 
			
		||||
                    child: const Text('checker'),
 | 
			
		||||
                  ),
 | 
			
		||||
                )
 | 
			
		||||
              ],
 | 
			
		||||
              ),
 | 
			
		||||
            ),
 | 
			
		||||
          ),
 | 
			
		||||
        ),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,12 @@
 | 
			
		|||
import 'package:crab_ui/contact.dart';
 | 
			
		||||
import 'package:flutter/material.dart';
 | 
			
		||||
import 'home_page.dart';
 | 
			
		||||
// import 'api_service.dart';
 | 
			
		||||
import 'login.dart';
 | 
			
		||||
import 'email.dart';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void main() {
 | 
			
		||||
  WidgetsFlutterBinding.ensureInitialized();
 | 
			
		||||
  // debugPaintSizeEnabled = true;
 | 
			
		||||
  runApp( HyM());
 | 
			
		||||
  runApp(HyM());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class HyM extends StatelessWidget {
 | 
			
		||||
| 
						 | 
				
			
			@ -22,11 +20,12 @@ class HyM extends StatelessWidget {
 | 
			
		|||
      theme: ThemeData.light(),
 | 
			
		||||
      title: 'HyM',
 | 
			
		||||
      // home: HomeScreen(),
 | 
			
		||||
      home: HomeScreen(),
 | 
			
		||||
      initialRoute: "/",
 | 
			
		||||
 | 
			
		||||
      routes: {
 | 
			
		||||
        "/": (context) => SplashScreen(),
 | 
			
		||||
        "/login": (context) => const LoginPage(),
 | 
			
		||||
        // "/email": (context) => EmailPage(),
 | 
			
		||||
        "/home": (context) => HomeScreen(),
 | 
			
		||||
        "/contacts": (context) => ContactsPage(),
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,14 +21,14 @@ class GetThreadResponse {
 | 
			
		|||
  factory GetThreadResponse.fromJson(Map<String, dynamic> json) {
 | 
			
		||||
    var toList = json['to'] as List<dynamic>;
 | 
			
		||||
 | 
			
		||||
    return GetThreadResponse (
 | 
			
		||||
    return GetThreadResponse(
 | 
			
		||||
      id: json['id'],
 | 
			
		||||
      messages: List<String>.from(json['messages']),
 | 
			
		||||
      subject: json['subject'],
 | 
			
		||||
      date: DateTime.parse(json['date']),
 | 
			
		||||
      from_name: json['from_name'],
 | 
			
		||||
      from_address: json['from_address'],
 | 
			
		||||
      to: toList.map((i)=> MailAddress.fromJson(i)).toList(),
 | 
			
		||||
      to: toList.map((i) => MailAddress.fromJson(i)).toList(),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -51,6 +51,7 @@ class MailAddress {
 | 
			
		|||
    return '${name} <${address}>';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// //old data structure
 | 
			
		||||
class SerializableMessage {
 | 
			
		||||
  final String name;
 | 
			
		||||
| 
						 | 
				
			
			@ -101,3 +102,19 @@ class SerializableMessage {
 | 
			
		|||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class AttachmentInfo {
 | 
			
		||||
  final String name;
 | 
			
		||||
  final int size;
 | 
			
		||||
  final String path;
 | 
			
		||||
 | 
			
		||||
  AttachmentInfo({required this.name, required this.size, required this.path});
 | 
			
		||||
 | 
			
		||||
  factory AttachmentInfo.fromJson(Map<String, dynamic> json) {
 | 
			
		||||
    return AttachmentInfo(
 | 
			
		||||
      name: json['name'],
 | 
			
		||||
      size: json['size'],
 | 
			
		||||
      path: json['path'],
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,10 @@ dependencies:
 | 
			
		|||
  http: 1.2.2
 | 
			
		||||
  flutter_html_all: 3.0.0-beta.2
 | 
			
		||||
  flutter_widget_from_html: ^0.10.0
 | 
			
		||||
  
 | 
			
		||||
  shared_preferences: ^2.0.6
 | 
			
		||||
  encrypt: ^5.0.0
 | 
			
		||||
  pointycastle: ^3.4.0
 | 
			
		||||
  mime: ^1.0.3
 | 
			
		||||
 | 
			
		||||
  english_words: ^4.0.0
 | 
			
		||||
  provider: ^6.0.0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue