NotSooFriendly94

home_screen.dart

Apr 9th, 2024
197
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 20.36 KB | Source Code | 0 0
  1. import 'package:flutter/material.dart';
  2. import 'package:intl/intl.dart';
  3. import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  4. import 'package:path_provider/path_provider.dart';
  5. import 'dart:convert';
  6. import 'dart:io';
  7. import 'package:metaballs/metaballs.dart'; // Import Metaballs package
  8.  
  9. class Reminder {
  10.   String name;
  11.   String priority;
  12.   DateTime? dueDate;
  13.  
  14.   Reminder({required this.name, required this.priority, this.dueDate});
  15. }
  16.  
  17. class HomeScreen extends StatefulWidget {
  18.   const HomeScreen({Key? key}) : super(key: key);
  19.  
  20.   @override
  21.   _HomeScreenState createState() => _HomeScreenState();
  22. }
  23.  
  24. class _HomeScreenState extends State<HomeScreen> {
  25.   final TextEditingController _reminderController = TextEditingController();
  26.   DateTime? selectedDate;
  27.   List<Reminder> reminders = [];
  28.   final ScrollController _scrollController = ScrollController();
  29.   bool _fadeInCompleted = false;
  30.   String _selectedFilter = 'Due Date';
  31.  
  32.   FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
  33.       FlutterLocalNotificationsPlugin();
  34.  
  35.   @override
  36.   void initState() {
  37.     super.initState();
  38.     _scrollController.addListener(_onScroll);
  39.     Future.delayed(const Duration(milliseconds: 1000), () {
  40.       _startFadeInAnimation();
  41.     });
  42.  
  43.     var initializationSettingsAndroid =
  44.         const AndroidInitializationSettings('@mipmap/ic_launcher');
  45.     var initializationSettings =
  46.         InitializationSettings(android: initializationSettingsAndroid);
  47.     flutterLocalNotificationsPlugin.initialize(initializationSettings);
  48.  
  49.     _loadReminders();
  50.   }
  51.  
  52.   @override
  53.   void dispose() {
  54.     _scrollController.removeListener(_onScroll);
  55.     _scrollController.dispose();
  56.     super.dispose();
  57.   }
  58.  
  59.   void _onScroll() {
  60.     setState(() {
  61.       // You can implement scrolling logic here if needed
  62.     });
  63.   }
  64.  
  65.   void _showNotification(String title, String body) async {
  66.   var androidPlatformChannelSpecifics = const AndroidNotificationDetails(
  67.     'your channel id',
  68.     'your channel name',
  69.     importance: Importance.max,
  70.     priority: Priority.high,
  71.     ticker: 'ticker',
  72.   );
  73.   var platformChannelSpecifics = NotificationDetails(
  74.     android: androidPlatformChannelSpecifics,
  75.   );
  76.   await flutterLocalNotificationsPlugin.show(
  77.     0,
  78.     title,
  79.     body,
  80.     platformChannelSpecifics,
  81.   );
  82. }
  83.  
  84.   void _startFadeInAnimation() {
  85.     Future.delayed(const Duration(milliseconds: 1000), () {
  86.       setState(() {
  87.         _fadeInCompleted = true;
  88.       });
  89.     });
  90.   }
  91.  
  92.   void _loadReminders() async {
  93.   final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  94.   final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
  95.   print('Searching for JSON files in directory: $directoryPath');
  96.   final Directory directory = Directory(directoryPath);
  97.  
  98.   if (directory.existsSync()) {
  99.     final List<FileSystemEntity> files = directory.listSync();
  100.     print('List of JSON files in directory:');
  101.    
  102.     for (final file in files) {
  103.       if (file is File && file.path.endsWith('.json')) {
  104.         print('File path: ${file.path}');
  105.         final String fileContents = await file.readAsString();
  106.         final Map<String, dynamic> reminderDetails = jsonDecode(fileContents) as Map<String, dynamic>;
  107.        
  108.         final String reminderName = reminderDetails['name'];
  109.         final String priority = reminderDetails['priority'];
  110.         final String dateString = reminderDetails['dueDate'];
  111.         final DateTime? dueDate = DateTime.tryParse(dateString);
  112.        
  113.         if (reminderName != null && priority != null && dueDate != null) {
  114.           setState(() {
  115.             final reminder = Reminder(
  116.               name: reminderName,
  117.               priority: priority,
  118.               dueDate: dueDate,
  119.             );
  120.             reminders.add(reminder);
  121.           });
  122.         }
  123.       }
  124.     }
  125.    
  126.     // Sort reminders immediately after loading
  127.     _sortReminders();
  128.   }
  129. }
  130.  
  131. DateTime? _parseDueDate(String dateString) {
  132.   try {
  133.     final List<String> dateParts = dateString.split('_');
  134.     if (dateParts.length == 3) {
  135.       final int day = int.parse(dateParts[0]);
  136.       final int month = int.parse(dateParts[1]);
  137.       final int year = int.parse(dateParts[2]);
  138.       return DateTime(year, month, day);
  139.     }
  140.   } catch (e) {
  141.     print('Error parsing due date: $e');
  142.   }
  143.   return null;
  144. }
  145.  
  146.   void _addReminder(DateTime selectedDate) async {
  147.   final newReminder = _reminderController.text.trim();
  148.   if (newReminder.isNotEmpty) {
  149.     setState(() {
  150.       final reminder = Reminder(
  151.         name: newReminder,
  152.         priority: 'Normal', // Default priority
  153.         dueDate: selectedDate,
  154.       );
  155.       reminders.add(reminder);
  156.       _scheduleNotification(newReminder, selectedDate);
  157.       _reminderController.clear();
  158.       _sortReminders(); // Sort reminders after adding a new one
  159.     });
  160.  
  161.     // Prepare reminder details
  162.     final reminderDetails = <String, dynamic>{
  163.       'name': newReminder,
  164.       'priority': 'Normal', // Default priority
  165.       'dueDate': DateFormat('dd_MM_yyyy').format(selectedDate), // Convert DateTime to formatted string
  166.     };
  167.  
  168.     // Convert reminderDetails map to JSON string
  169.     final jsonString = jsonEncode(reminderDetails);
  170.  
  171.     // Print JSON string
  172.     print('Reminder details to be saved to JSON file: $jsonString');
  173.  
  174.     // Save reminder details to JSON file
  175.     _saveReminderToFileAsync(reminderDetails);
  176.  
  177.     // Print file path and name
  178.     final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  179.     final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
  180.     final fileName = '${reminderDetails['name']}_${reminderDetails['dueDate']}.json';
  181.     print('Reminder details saved to: $directoryPath/$fileName');
  182.   } else {
  183.     // Show a styled Snackbar if reminder text is empty
  184.     ScaffoldMessenger.of(context).showSnackBar(
  185.       SnackBar(
  186.         behavior: SnackBarBehavior.floating,
  187.         elevation: 0,
  188.         content: Container(
  189.           height: 40,
  190.           alignment: Alignment.center,
  191.           padding: const EdgeInsets.symmetric(horizontal: 16.0),
  192.           decoration: BoxDecoration(
  193.             color: const Color.fromARGB(133, 255, 0, 0),
  194.             borderRadius: BorderRadius.circular(20),
  195.             border: Border.all(color: Colors.white),
  196.           ),
  197.           child: const Text(
  198.             'Please enter a reminder',
  199.             textAlign: TextAlign.center,
  200.             style: TextStyle(
  201.               color: Colors.white,
  202.               fontSize: 15,
  203.             ),
  204.           ),
  205.         ),
  206.         duration: const Duration(seconds: 4),
  207.         margin: const EdgeInsets.only(bottom: 20),
  208.       ),
  209.     );
  210.   }
  211. }
  212.  
  213.   Future<void> _saveReminderToFileAsync(Map<String, dynamic> reminderDetails) async {
  214.     final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  215.     final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
  216.     final Directory directory = Directory(directoryPath);
  217.  
  218.     // Create directory if it doesn't exist
  219.     if (!directory.existsSync()) {
  220.       directory.createSync(recursive: true);
  221.       print('Directory created: $directoryPath');
  222.     }
  223.  
  224.     // Generate filename
  225.     final String fileName = '${reminderDetails['name']}_${reminderDetails['dueDate']}.json';
  226.     final File file = File('$directoryPath/$fileName');
  227.     await file.writeAsString(jsonEncode(reminderDetails));
  228.     print('Reminder details saved to: ${file.path}');
  229.   }
  230.  
  231.   void _updateReminderInFile(Reminder oldReminder, Reminder newReminder) async {
  232.     final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  233.     final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
  234.     final Directory directory = Directory(directoryPath);
  235.     if (directory.existsSync()) {
  236.       final List<FileSystemEntity> files = directory.listSync();
  237.       for (final file in files) {
  238.         if (file is File) {
  239.           final String fileContents = await file.readAsString();
  240.           final Map<String, dynamic> reminderDetails =
  241.               jsonDecode(fileContents) as Map<String, dynamic>;
  242.           if (reminderDetails['name'] == oldReminder.name) {
  243.             reminderDetails['name'] = newReminder.name;
  244.             reminderDetails['priority'] = newReminder.priority;
  245.             reminderDetails['dueDate'] = newReminder.dueDate!.toIso8601String();
  246.             await file.writeAsString(jsonEncode(reminderDetails));
  247.             print('File Successfully updated: ${file.path}');
  248.             break;
  249.           }
  250.         }
  251.       }
  252.     }
  253.   }
  254.  
  255.   void _deleteReminderFile(Reminder reminder) async {
  256.     final appDocumentsDirectory = await getApplicationDocumentsDirectory();
  257.     final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
  258.     final String fileName =
  259.         '${reminder.name}_${DateFormat('dd_MM_yyyy').format(reminder.dueDate!)}.json';
  260.     final File file = File('$directoryPath/$fileName');
  261.     if (file.existsSync()) {
  262.       await file.delete();
  263.       print('Reminder details deleted: ${file.path}');
  264.     } else {
  265.       print('Reminder details file does not exist: ${file.path}');
  266.     }
  267.   }
  268.  
  269.   void _scheduleNotification(String reminder, DateTime dueDate) {
  270.     final now = DateTime.now();
  271.     final difference = dueDate.difference(now);
  272.     final seconds = difference.inSeconds;
  273.     final notificationTime = now.add(Duration(seconds: seconds));
  274.  
  275.     _showNotification(reminder, 'Reminder: $reminder');
  276.   }
  277.  
  278.   void _sortReminders() {
  279.     setState(() {
  280.       if (_selectedFilter == 'Due Date') {
  281.         reminders.sort((a, b) => a.dueDate!.compareTo(b.dueDate!));
  282.       } else {
  283.         reminders.sort((a, b) {
  284.           if (a.priority == b.priority) {
  285.             return 0;
  286.           } else if (a.priority == 'High') {
  287.             return -1;
  288.           } else if (b.priority == 'High') {
  289.             return 1;
  290.           } else if (a.priority == 'Normal') {
  291.             return -1;
  292.           } else {
  293.             return 1;
  294.           }
  295.         });
  296.       }
  297.     });
  298.   }
  299.  
  300. Color _getReminderTileColor(String priority) {
  301.   switch (priority) {
  302.     case 'Low':
  303.       return const Color.fromARGB(167, 0, 255, 8); // Transparent green
  304.     case 'Normal':
  305.       return const Color.fromARGB(184, 0, 140, 255); // Transparent blue
  306.     case 'High':
  307.       return const Color.fromARGB(164, 255, 17, 0); // Transparent red
  308.     default:
  309.       return const Color.fromARGB(184, 0, 140, 255); // Transparent blue (Default)
  310.   }
  311. }
  312.  
  313.  @override
  314. Widget build(BuildContext context) {
  315.   return Metaballs(
  316.     color: const Color.fromARGB(255, 66, 133, 244),
  317.     effect: MetaballsEffect.follow(
  318.       growthFactor: 1,
  319.       smoothing: 1,
  320.       radius: 0.5,
  321.     ),
  322.     gradient: const LinearGradient(
  323.       colors: [Color.fromARGB(160, 17, 0, 113), Color.fromARGB(173, 128, 0, 255)],
  324.       begin: Alignment.bottomRight,
  325.       end: Alignment.topLeft,
  326.     ),
  327.     metaballs: 20,
  328.     animationDuration: const Duration(milliseconds: 200),
  329.     speedMultiplier: 1,
  330.     bounceStiffness: 3,
  331.     minBallRadius: 30,
  332.     maxBallRadius: 60,
  333.     glowRadius: 0.7,
  334.     glowIntensity: 0.6,
  335.     child: AnimatedOpacity(
  336.       opacity: _fadeInCompleted ? 1.0 : 0.0,
  337.       duration: const Duration(milliseconds: 1500),
  338.       child: Scaffold(
  339.         backgroundColor: const Color.fromARGB(103, 145, 145, 145),
  340.         appBar: AppBar(
  341.           backgroundColor: const Color.fromARGB(0, 145, 145, 145),
  342.           title: const Text(
  343.             'Home Reminders',
  344.             style: TextStyle(color: Colors.white),
  345.           ),
  346.           centerTitle: true,
  347.         ),
  348.         body: Padding(
  349.           padding: const EdgeInsets.all(16.0),
  350.           child: Column(
  351.             crossAxisAlignment: CrossAxisAlignment.start,
  352.             children: [
  353.               TextField(
  354.                 controller: _reminderController,
  355.                 decoration: const InputDecoration(
  356.                   hintText: 'Enter Reminder',
  357.                   hintStyle: TextStyle(color: Colors.white, fontSize: 20),
  358.                 ),
  359.                 onChanged: (_) {
  360.                   setState(() {});
  361.                 },
  362.                 style: const TextStyle(color: Colors.white, fontSize: 20.0),
  363.               ),
  364.               const SizedBox(height: 20),
  365.               Row(
  366.                 children: [
  367.                   Expanded(
  368.                     child: ElevatedButton(
  369.                       onPressed: () async {
  370.                         final pickedDate = await showDatePicker(
  371.                           context: context,
  372.                           initialDate: DateTime.now(),
  373.                           firstDate: DateTime.now(),
  374.                           lastDate: DateTime(2100),
  375.                         );
  376.                         if (pickedDate != null) {
  377.                           setState(() {
  378.                             selectedDate = pickedDate;
  379.                           });
  380.                         }
  381.                       },
  382.                       style: ElevatedButton.styleFrom(
  383.                         foregroundColor: Colors.white,
  384.                         backgroundColor: const Color.fromARGB(100, 132, 58, 217),
  385.                         shape: RoundedRectangleBorder(
  386.                           borderRadius: BorderRadius.circular(10),
  387.                           side: const BorderSide(color: Color.fromARGB(255, 132, 58, 217)),
  388.                         ),
  389.                       ),
  390.                       child: Text(
  391.                         selectedDate == null
  392.                             ? 'Select Due Date'
  393.                             : DateFormat('dd/MM/yyyy').format(selectedDate!),
  394.                         style: const TextStyle(fontSize: 17),
  395.                       ),
  396.                     ),
  397.                   ),
  398.                   const SizedBox(width: 20),
  399.                   ElevatedButton(
  400.                     onPressed: () {
  401.                       if (selectedDate != null) {
  402.                         _addReminder(selectedDate!);
  403.                       } else {
  404.                         ScaffoldMessenger.of(context).showSnackBar(
  405.                           SnackBar(
  406.                             content: Text('Please select a due date first'),
  407.                             duration: Duration(seconds: 2),
  408.                           ),
  409.                         );
  410.                       }
  411.                     },
  412.                     style: ElevatedButton.styleFrom(
  413.                       foregroundColor: Colors.white,
  414.                       backgroundColor: const Color.fromARGB(100, 132, 58, 217),
  415.                       shape: RoundedRectangleBorder(
  416.                         borderRadius: BorderRadius.circular(10),
  417.                         side: const BorderSide(color: Color.fromARGB(255, 132, 58, 217)),
  418.                       ),
  419.                     ),
  420.                     child: const Text(
  421.                       'Add Reminder',
  422.                       style: TextStyle(fontSize: 17),
  423.                     ),
  424.                   ),
  425.                 ],
  426.               ),
  427.               const SizedBox(height: 70),
  428.               Row(
  429.                 children: [
  430.                   Expanded(
  431.                     child: DropdownButton<String>(
  432.                       value: _selectedFilter,
  433.                       onChanged: (String? newValue) {
  434.                         setState(() {
  435.                           _selectedFilter = newValue!;
  436.                           _sortReminders();
  437.                         });
  438.                       },
  439.                       dropdownColor: const Color.fromARGB(100, 132, 58, 217),
  440.                       style: const TextStyle(color: Colors.white, fontSize: 20),
  441.                       iconSize: 30,
  442.                       iconEnabledColor: Colors.white,
  443.                       iconDisabledColor: Colors.white,
  444.                       items: <String>['Due Date', 'Importance'].map<DropdownMenuItem<String>>(
  445.                         (String value) {
  446.                           return DropdownMenuItem<String>(
  447.                             value: value,
  448.                             child: Text(value),
  449.                           );
  450.                         },
  451.                       ).toList(),
  452.                     ),
  453.                   ),
  454.                 ],
  455.               ),
  456.               const SizedBox(height: 30),
  457.               const Text(
  458.                 'Reminders:',
  459.                 style: TextStyle(
  460.                   fontSize: 20.0,
  461.                   fontWeight: FontWeight.bold,
  462.                   color: Colors.white,
  463.                 ),
  464.               ),
  465.               const SizedBox(height: 10),
  466.               Expanded(
  467.                 child: ListView.builder(
  468.                   controller: _scrollController,
  469.                   itemCount: reminders.length,
  470.                   itemBuilder: (BuildContext context, int index) {
  471.                     final reminder = reminders[index];
  472.                     return Padding(
  473.                       padding: const EdgeInsets.symmetric(vertical: 10.0),
  474.                       child: ClipRRect(
  475.                         borderRadius: BorderRadius.circular(15.0),
  476.                         child: Container(
  477.                           color: _getReminderTileColor(reminder.priority),
  478.                           child: Dismissible(
  479.                             key: UniqueKey(),
  480.                             direction: DismissDirection.horizontal,
  481.                             background: Container(
  482.                               color: Colors.blue,
  483.                               alignment: Alignment.centerLeft,
  484.                               child: const Padding(
  485.                                 padding: EdgeInsets.only(left: 20.0),
  486.                                 child: Icon(Icons.edit, color: Colors.white),
  487.                               ),
  488.                             ),
  489.                             secondaryBackground: Container(
  490.                               color: Colors.red,
  491.                               alignment: Alignment.centerRight,
  492.                               child: const Padding(
  493.                                 padding: EdgeInsets.only(right: 20.0),
  494.                                 child: Icon(Icons.delete, color: Colors.white),
  495.                               ),
  496.                             ),
  497.                             onDismissed: (direction) {
  498.                               setState(() {
  499.                                 reminders.removeAt(index);
  500.                                 _deleteReminderFile(reminder);
  501.                               });
  502.                             },
  503.                             child: ListTile(
  504.                               title: Text(reminder.name, style: const TextStyle(color: Colors.white, fontSize: 20)),
  505.                               subtitle: Text(
  506.                                 reminder.dueDate != null
  507.                                     ? 'Due Date: ${DateFormat('dd/MM/yyyy').format(reminder.dueDate!)}'
  508.                                     : 'Due Date: Not set',
  509.                                 style: const TextStyle(color: Colors.white, fontSize: 15),
  510.                               ),
  511.                               trailing: DropdownButton<String>(
  512.                                 iconSize: 30,
  513.                                 dropdownColor: const Color.fromARGB(170, 132, 58, 217),
  514.                                 value: reminder.priority,
  515.                                 onChanged: (String? newValue) {
  516.                                   setState(() {
  517.                                     reminder.priority = newValue!;
  518.                                     _updateReminderInFile(reminder, reminder);
  519.                                   });
  520.                                 },
  521.                                 items: <String>['Low', 'Normal', 'High'].map<DropdownMenuItem<String>>(
  522.                                   (String value) {
  523.                                     return DropdownMenuItem<String>(
  524.                                       value: value,
  525.                                       child: Text(value, style: const TextStyle(color: Colors.white, fontSize: 20)),
  526.                                     );
  527.                                   },
  528.                                 ).toList(),
  529.                               ),
  530.                             ),
  531.                           ),
  532.                         ),
  533.                       ),
  534.                     );
  535.                   },
  536.                 ),
  537.               ),
  538.             ],
  539.           ),
  540.         ),
  541.       ),
  542.     ),
  543.   );
  544. }
  545.  
  546. }
  547.  
Advertisement
Add Comment
Please, Sign In to add comment