Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import 'package:flutter/material.dart';
- import 'package:intl/intl.dart';
- import 'package:flutter_local_notifications/flutter_local_notifications.dart';
- import 'package:path_provider/path_provider.dart';
- import 'dart:convert';
- import 'dart:io';
- import 'package:metaballs/metaballs.dart'; // Import Metaballs package
- class Reminder {
- String name;
- String priority;
- DateTime? dueDate;
- Reminder({required this.name, required this.priority, this.dueDate});
- }
- class HomeScreen extends StatefulWidget {
- const HomeScreen({Key? key}) : super(key: key);
- @override
- _HomeScreenState createState() => _HomeScreenState();
- }
- class _HomeScreenState extends State<HomeScreen> {
- final TextEditingController _reminderController = TextEditingController();
- DateTime? selectedDate;
- List<Reminder> reminders = [];
- final ScrollController _scrollController = ScrollController();
- bool _fadeInCompleted = false;
- String _selectedFilter = 'Due Date';
- FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
- FlutterLocalNotificationsPlugin();
- @override
- void initState() {
- super.initState();
- _scrollController.addListener(_onScroll);
- Future.delayed(const Duration(milliseconds: 1000), () {
- _startFadeInAnimation();
- });
- var initializationSettingsAndroid =
- const AndroidInitializationSettings('@mipmap/ic_launcher');
- var initializationSettings =
- InitializationSettings(android: initializationSettingsAndroid);
- flutterLocalNotificationsPlugin.initialize(initializationSettings);
- _loadReminders();
- }
- @override
- void dispose() {
- _scrollController.removeListener(_onScroll);
- _scrollController.dispose();
- super.dispose();
- }
- void _onScroll() {
- setState(() {
- // You can implement scrolling logic here if needed
- });
- }
- void _showNotification(String title, String body) async {
- var androidPlatformChannelSpecifics = const AndroidNotificationDetails(
- 'your channel id',
- 'your channel name',
- importance: Importance.max,
- priority: Priority.high,
- ticker: 'ticker',
- );
- var platformChannelSpecifics = NotificationDetails(
- android: androidPlatformChannelSpecifics,
- );
- await flutterLocalNotificationsPlugin.show(
- 0,
- title,
- body,
- platformChannelSpecifics,
- );
- }
- void _startFadeInAnimation() {
- Future.delayed(const Duration(milliseconds: 1000), () {
- setState(() {
- _fadeInCompleted = true;
- });
- });
- }
- void _loadReminders() async {
- final appDocumentsDirectory = await getApplicationDocumentsDirectory();
- final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
- print('Searching for JSON files in directory: $directoryPath');
- final Directory directory = Directory(directoryPath);
- if (directory.existsSync()) {
- final List<FileSystemEntity> files = directory.listSync();
- print('List of JSON files in directory:');
- for (final file in files) {
- if (file is File && file.path.endsWith('.json')) {
- print('File path: ${file.path}');
- final String fileContents = await file.readAsString();
- final Map<String, dynamic> reminderDetails = jsonDecode(fileContents) as Map<String, dynamic>;
- final String reminderName = reminderDetails['name'];
- final String priority = reminderDetails['priority'];
- final String dateString = reminderDetails['dueDate'];
- final DateTime? dueDate = DateTime.tryParse(dateString);
- if (reminderName != null && priority != null && dueDate != null) {
- setState(() {
- final reminder = Reminder(
- name: reminderName,
- priority: priority,
- dueDate: dueDate,
- );
- reminders.add(reminder);
- });
- }
- }
- }
- // Sort reminders immediately after loading
- _sortReminders();
- }
- }
- DateTime? _parseDueDate(String dateString) {
- try {
- final List<String> dateParts = dateString.split('_');
- if (dateParts.length == 3) {
- final int day = int.parse(dateParts[0]);
- final int month = int.parse(dateParts[1]);
- final int year = int.parse(dateParts[2]);
- return DateTime(year, month, day);
- }
- } catch (e) {
- print('Error parsing due date: $e');
- }
- return null;
- }
- void _addReminder(DateTime selectedDate) async {
- final newReminder = _reminderController.text.trim();
- if (newReminder.isNotEmpty) {
- setState(() {
- final reminder = Reminder(
- name: newReminder,
- priority: 'Normal', // Default priority
- dueDate: selectedDate,
- );
- reminders.add(reminder);
- _scheduleNotification(newReminder, selectedDate);
- _reminderController.clear();
- _sortReminders(); // Sort reminders after adding a new one
- });
- // Prepare reminder details
- final reminderDetails = <String, dynamic>{
- 'name': newReminder,
- 'priority': 'Normal', // Default priority
- 'dueDate': DateFormat('dd_MM_yyyy').format(selectedDate), // Convert DateTime to formatted string
- };
- // Convert reminderDetails map to JSON string
- final jsonString = jsonEncode(reminderDetails);
- // Print JSON string
- print('Reminder details to be saved to JSON file: $jsonString');
- // Save reminder details to JSON file
- _saveReminderToFileAsync(reminderDetails);
- // Print file path and name
- final appDocumentsDirectory = await getApplicationDocumentsDirectory();
- final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
- final fileName = '${reminderDetails['name']}_${reminderDetails['dueDate']}.json';
- print('Reminder details saved to: $directoryPath/$fileName');
- } else {
- // Show a styled Snackbar if reminder text is empty
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- behavior: SnackBarBehavior.floating,
- elevation: 0,
- content: Container(
- height: 40,
- alignment: Alignment.center,
- padding: const EdgeInsets.symmetric(horizontal: 16.0),
- decoration: BoxDecoration(
- color: const Color.fromARGB(133, 255, 0, 0),
- borderRadius: BorderRadius.circular(20),
- border: Border.all(color: Colors.white),
- ),
- child: const Text(
- 'Please enter a reminder',
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- fontSize: 15,
- ),
- ),
- ),
- duration: const Duration(seconds: 4),
- margin: const EdgeInsets.only(bottom: 20),
- ),
- );
- }
- }
- Future<void> _saveReminderToFileAsync(Map<String, dynamic> reminderDetails) async {
- final appDocumentsDirectory = await getApplicationDocumentsDirectory();
- final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
- final Directory directory = Directory(directoryPath);
- // Create directory if it doesn't exist
- if (!directory.existsSync()) {
- directory.createSync(recursive: true);
- print('Directory created: $directoryPath');
- }
- // Generate filename
- final String fileName = '${reminderDetails['name']}_${reminderDetails['dueDate']}.json';
- final File file = File('$directoryPath/$fileName');
- await file.writeAsString(jsonEncode(reminderDetails));
- print('Reminder details saved to: ${file.path}');
- }
- void _updateReminderInFile(Reminder oldReminder, Reminder newReminder) async {
- final appDocumentsDirectory = await getApplicationDocumentsDirectory();
- final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
- final Directory directory = Directory(directoryPath);
- if (directory.existsSync()) {
- final List<FileSystemEntity> files = directory.listSync();
- for (final file in files) {
- if (file is File) {
- final String fileContents = await file.readAsString();
- final Map<String, dynamic> reminderDetails =
- jsonDecode(fileContents) as Map<String, dynamic>;
- if (reminderDetails['name'] == oldReminder.name) {
- reminderDetails['name'] = newReminder.name;
- reminderDetails['priority'] = newReminder.priority;
- reminderDetails['dueDate'] = newReminder.dueDate!.toIso8601String();
- await file.writeAsString(jsonEncode(reminderDetails));
- print('File Successfully updated: ${file.path}');
- break;
- }
- }
- }
- }
- }
- void _deleteReminderFile(Reminder reminder) async {
- final appDocumentsDirectory = await getApplicationDocumentsDirectory();
- final String directoryPath = '${appDocumentsDirectory.path}/Reminders';
- final String fileName =
- '${reminder.name}_${DateFormat('dd_MM_yyyy').format(reminder.dueDate!)}.json';
- final File file = File('$directoryPath/$fileName');
- if (file.existsSync()) {
- await file.delete();
- print('Reminder details deleted: ${file.path}');
- } else {
- print('Reminder details file does not exist: ${file.path}');
- }
- }
- void _scheduleNotification(String reminder, DateTime dueDate) {
- final now = DateTime.now();
- final difference = dueDate.difference(now);
- final seconds = difference.inSeconds;
- final notificationTime = now.add(Duration(seconds: seconds));
- _showNotification(reminder, 'Reminder: $reminder');
- }
- void _sortReminders() {
- setState(() {
- if (_selectedFilter == 'Due Date') {
- reminders.sort((a, b) => a.dueDate!.compareTo(b.dueDate!));
- } else {
- reminders.sort((a, b) {
- if (a.priority == b.priority) {
- return 0;
- } else if (a.priority == 'High') {
- return -1;
- } else if (b.priority == 'High') {
- return 1;
- } else if (a.priority == 'Normal') {
- return -1;
- } else {
- return 1;
- }
- });
- }
- });
- }
- Color _getReminderTileColor(String priority) {
- switch (priority) {
- case 'Low':
- return const Color.fromARGB(167, 0, 255, 8); // Transparent green
- case 'Normal':
- return const Color.fromARGB(184, 0, 140, 255); // Transparent blue
- case 'High':
- return const Color.fromARGB(164, 255, 17, 0); // Transparent red
- default:
- return const Color.fromARGB(184, 0, 140, 255); // Transparent blue (Default)
- }
- }
- @override
- Widget build(BuildContext context) {
- return Metaballs(
- color: const Color.fromARGB(255, 66, 133, 244),
- effect: MetaballsEffect.follow(
- growthFactor: 1,
- smoothing: 1,
- radius: 0.5,
- ),
- gradient: const LinearGradient(
- colors: [Color.fromARGB(160, 17, 0, 113), Color.fromARGB(173, 128, 0, 255)],
- begin: Alignment.bottomRight,
- end: Alignment.topLeft,
- ),
- metaballs: 20,
- animationDuration: const Duration(milliseconds: 200),
- speedMultiplier: 1,
- bounceStiffness: 3,
- minBallRadius: 30,
- maxBallRadius: 60,
- glowRadius: 0.7,
- glowIntensity: 0.6,
- child: AnimatedOpacity(
- opacity: _fadeInCompleted ? 1.0 : 0.0,
- duration: const Duration(milliseconds: 1500),
- child: Scaffold(
- backgroundColor: const Color.fromARGB(103, 145, 145, 145),
- appBar: AppBar(
- backgroundColor: const Color.fromARGB(0, 145, 145, 145),
- title: const Text(
- 'Home Reminders',
- style: TextStyle(color: Colors.white),
- ),
- centerTitle: true,
- ),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- TextField(
- controller: _reminderController,
- decoration: const InputDecoration(
- hintText: 'Enter Reminder',
- hintStyle: TextStyle(color: Colors.white, fontSize: 20),
- ),
- onChanged: (_) {
- setState(() {});
- },
- style: const TextStyle(color: Colors.white, fontSize: 20.0),
- ),
- const SizedBox(height: 20),
- Row(
- children: [
- Expanded(
- child: ElevatedButton(
- onPressed: () async {
- final pickedDate = await showDatePicker(
- context: context,
- initialDate: DateTime.now(),
- firstDate: DateTime.now(),
- lastDate: DateTime(2100),
- );
- if (pickedDate != null) {
- setState(() {
- selectedDate = pickedDate;
- });
- }
- },
- style: ElevatedButton.styleFrom(
- foregroundColor: Colors.white,
- backgroundColor: const Color.fromARGB(100, 132, 58, 217),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
- side: const BorderSide(color: Color.fromARGB(255, 132, 58, 217)),
- ),
- ),
- child: Text(
- selectedDate == null
- ? 'Select Due Date'
- : DateFormat('dd/MM/yyyy').format(selectedDate!),
- style: const TextStyle(fontSize: 17),
- ),
- ),
- ),
- const SizedBox(width: 20),
- ElevatedButton(
- onPressed: () {
- if (selectedDate != null) {
- _addReminder(selectedDate!);
- } else {
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(
- content: Text('Please select a due date first'),
- duration: Duration(seconds: 2),
- ),
- );
- }
- },
- style: ElevatedButton.styleFrom(
- foregroundColor: Colors.white,
- backgroundColor: const Color.fromARGB(100, 132, 58, 217),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(10),
- side: const BorderSide(color: Color.fromARGB(255, 132, 58, 217)),
- ),
- ),
- child: const Text(
- 'Add Reminder',
- style: TextStyle(fontSize: 17),
- ),
- ),
- ],
- ),
- const SizedBox(height: 70),
- Row(
- children: [
- Expanded(
- child: DropdownButton<String>(
- value: _selectedFilter,
- onChanged: (String? newValue) {
- setState(() {
- _selectedFilter = newValue!;
- _sortReminders();
- });
- },
- dropdownColor: const Color.fromARGB(100, 132, 58, 217),
- style: const TextStyle(color: Colors.white, fontSize: 20),
- iconSize: 30,
- iconEnabledColor: Colors.white,
- iconDisabledColor: Colors.white,
- items: <String>['Due Date', 'Importance'].map<DropdownMenuItem<String>>(
- (String value) {
- return DropdownMenuItem<String>(
- value: value,
- child: Text(value),
- );
- },
- ).toList(),
- ),
- ),
- ],
- ),
- const SizedBox(height: 30),
- const Text(
- 'Reminders:',
- style: TextStyle(
- fontSize: 20.0,
- fontWeight: FontWeight.bold,
- color: Colors.white,
- ),
- ),
- const SizedBox(height: 10),
- Expanded(
- child: ListView.builder(
- controller: _scrollController,
- itemCount: reminders.length,
- itemBuilder: (BuildContext context, int index) {
- final reminder = reminders[index];
- return Padding(
- padding: const EdgeInsets.symmetric(vertical: 10.0),
- child: ClipRRect(
- borderRadius: BorderRadius.circular(15.0),
- child: Container(
- color: _getReminderTileColor(reminder.priority),
- child: Dismissible(
- key: UniqueKey(),
- direction: DismissDirection.horizontal,
- background: Container(
- color: Colors.blue,
- alignment: Alignment.centerLeft,
- child: const Padding(
- padding: EdgeInsets.only(left: 20.0),
- child: Icon(Icons.edit, color: Colors.white),
- ),
- ),
- secondaryBackground: Container(
- color: Colors.red,
- alignment: Alignment.centerRight,
- child: const Padding(
- padding: EdgeInsets.only(right: 20.0),
- child: Icon(Icons.delete, color: Colors.white),
- ),
- ),
- onDismissed: (direction) {
- setState(() {
- reminders.removeAt(index);
- _deleteReminderFile(reminder);
- });
- },
- child: ListTile(
- title: Text(reminder.name, style: const TextStyle(color: Colors.white, fontSize: 20)),
- subtitle: Text(
- reminder.dueDate != null
- ? 'Due Date: ${DateFormat('dd/MM/yyyy').format(reminder.dueDate!)}'
- : 'Due Date: Not set',
- style: const TextStyle(color: Colors.white, fontSize: 15),
- ),
- trailing: DropdownButton<String>(
- iconSize: 30,
- dropdownColor: const Color.fromARGB(170, 132, 58, 217),
- value: reminder.priority,
- onChanged: (String? newValue) {
- setState(() {
- reminder.priority = newValue!;
- _updateReminderInFile(reminder, reminder);
- });
- },
- items: <String>['Low', 'Normal', 'High'].map<DropdownMenuItem<String>>(
- (String value) {
- return DropdownMenuItem<String>(
- value: value,
- child: Text(value, style: const TextStyle(color: Colors.white, fontSize: 20)),
- );
- },
- ).toList(),
- ),
- ),
- ),
- ),
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment