Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Email reminders #161

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ app.*.map.json
/android/app/debug
/android/app/profile
/android/app/release

/.env
56 changes: 56 additions & 0 deletions ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,40 @@
PODS:
- audioplayers_darwin (0.0.1):
- Flutter
- DKImagePickerController/Core (4.3.9):
- DKImagePickerController/ImageDataManager
- DKImagePickerController/Resource
- DKImagePickerController/ImageDataManager (4.3.9)
- DKImagePickerController/PhotoGallery (4.3.9):
- DKImagePickerController/Core
- DKPhotoGallery
- DKImagePickerController/Resource (4.3.9)
- DKPhotoGallery (0.0.19):
- DKPhotoGallery/Core (= 0.0.19)
- DKPhotoGallery/Model (= 0.0.19)
- DKPhotoGallery/Preview (= 0.0.19)
- DKPhotoGallery/Resource (= 0.0.19)
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Core (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Preview
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Model (0.0.19):
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Preview (0.0.19):
- DKPhotoGallery/Model
- DKPhotoGallery/Resource
- SDWebImage
- SwiftyGif
- DKPhotoGallery/Resource (0.0.19):
- SDWebImage
- SwiftyGif
- file_picker (0.0.1):
- DKImagePickerController/PhotoGallery
- Flutter
- Flutter (1.0.0)
- flutter_keyboard_visibility (0.0.1):
- Flutter
Expand All @@ -10,33 +44,47 @@ PODS:
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- SDWebImage (5.19.7):
- SDWebImage/Core (= 5.19.7)
- SDWebImage/Core (5.19.7)
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- speech_to_text (0.0.1):
- Flutter
- FlutterMacOS
- Try
- SwiftyGif (5.4.5)
- Toast (4.1.1)
- Try (2.1.1)
- url_launcher_ios (0.0.1):
- Flutter

DEPENDENCIES:
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/ios`)
- file_picker (from `.symlinks/plugins/file_picker/ios`)
- Flutter (from `Flutter`)
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- speech_to_text (from `.symlinks/plugins/speech_to_text/darwin`)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)

SPEC REPOS:
trunk:
- DKImagePickerController
- DKPhotoGallery
- SDWebImage
- SwiftyGif
- Toast
- Try

EXTERNAL SOURCES:
audioplayers_darwin:
:path: ".symlinks/plugins/audioplayers_darwin/ios"
file_picker:
:path: ".symlinks/plugins/file_picker/ios"
Flutter:
:path: Flutter
flutter_keyboard_visibility:
Expand All @@ -49,17 +97,25 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
speech_to_text:
:path: ".symlinks/plugins/speech_to_text/darwin"
url_launcher_ios:
:path: ".symlinks/plugins/url_launcher_ios/ios"

SPEC CHECKSUMS:
audioplayers_darwin: ccf9c770ee768abb07e26d90af093f7bab1c12ab
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619
fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
speech_to_text: 9dc43a5df3cbc2813f8c7cc9bd0fbf94268ed7ac
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96
url_launcher_ios: 694010445543906933d732453a59da0a173ae33d

PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796

Expand Down
11 changes: 11 additions & 0 deletions lib/enums/reminder_interval.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
enum ReminderInterval {
oneHour("Before 1hr", 1),
fiveHour("Before 5hr", 5),
oneDay("Before 1 day", 24),
twoDay("Before 2 days", 48),
oneWeek("Before 1 week", 168);

const ReminderInterval(this.title, this.interval);
final String title;
final int interval;
}
1 change: 1 addition & 0 deletions lib/enums/taskoptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ enum TaskOption {
launchMeditationScreen,
toggleTipVisibility,
exportToCSV,
emailReminders,
}
32 changes: 26 additions & 6 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:provider/provider.dart';
import 'package:taskly/providers/theme_provider.dart';
import 'package:taskly/screens/home_screen.dart';
import 'package:taskly/screens/intro_screen.dart';
import 'package:taskly/screens/splash_screen.dart';
import 'package:taskly/service/email_service.dart';
import 'package:taskly/service/local_db_service.dart';
import 'package:taskly/service/speech_service.dart';
import 'package:workmanager/workmanager.dart';

void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
await EmailService.sendMessage(
inputData!['recipient'],
inputData['title'],
inputData['desc'],
inputData['deadline'],
);
return Future.value(true);
});
}

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true,
);
bool first = await LocalDbService.getFirstTime();
await dotenv.load(fileName: ".env");

runApp(TasklyApp(
isFirstTime: first,
));
Expand All @@ -29,12 +50,10 @@ class TasklyApp extends StatefulWidget {
class _TasklyAppState extends State<TasklyApp> {
late ThemeProvider themeProvider;


@override
void initState() {
super.initState();
themeProvider =
ThemeProvider();
themeProvider = ThemeProvider();
SpeechService.intialize();
}

Expand All @@ -52,14 +71,15 @@ class _TasklyAppState extends State<TasklyApp> {
),
darkTheme: ThemeData.dark().copyWith(
textTheme: ThemeData.dark().textTheme.apply(
fontFamily: 'Quicksand',
),
fontFamily: 'Quicksand',
),
),
themeMode: value.darkTheme ? ThemeMode.dark : ThemeMode.light,
// home: widget.isFirstTime ? const IntroScreen() : const HomeScreen(),
initialRoute: '/',
routes: {
'/': (context) => SplashScreen(), // Add Splash Screen as the initial route
'/': (context) =>
SplashScreen(), // Add Splash Screen as the initial route
'/main': (context) =>
widget.isFirstTime ? const IntroScreen() : const HomeScreen(),
},
Expand Down
28 changes: 16 additions & 12 deletions lib/models/task.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,23 @@ class Task {
Color color;
int? recurringDays;
Task? dependency;
int? reminder; // hrs before deadline

bool get isRecurring => recurringDays != null;

bool get hasDeadline => deadline != null;

Task(
{required this.title,
this.description = '',
this.isCompleted = false,
this.deadline,
this.color = Colors.blue,
this.recurringDays,
this.dependency,
String? id})
: id = id ?? DateTime.now().microsecondsSinceEpoch.toString();
Task({
required this.title,
this.description = '',
this.isCompleted = false,
this.deadline,
this.color = Colors.blue,
this.recurringDays,
this.dependency,
String? id,
this.reminder,
}) : id = id ?? DateTime.now().microsecondsSinceEpoch.toString();

// Convert a Task object to JSON
Map<String, dynamic> toJson() {
Expand All @@ -36,6 +38,7 @@ class Task {
'recurringDays': recurringDays,
'color': color.value,
'id': id,
'reminder': reminder,
};
}

Expand All @@ -45,12 +48,13 @@ class Task {
title: json['title'],
description: json['description'],
isCompleted: json['isCompleted'],
deadline: DateTime.parse(json['deadline']),
deadline: DateTime.tryParse(json['deadline'] ?? ""),
dependency:
json['dependency'] != null ? Task.fromJson(json['dependency']) : null,
recurringDays: json['recurringDays'],
color: Color(json['color']),
id: json['id'] ?? DateTime.now().millisecondsSinceEpoch.toString(),
reminder: json['reminder'],
);
}

Expand All @@ -68,6 +72,6 @@ class Task {

@override
String toString() {
return 'Task(id: $id, title: $title, description: $description, isCompleted: $isCompleted, deadline: $deadline, hasDeadline: $hasDeadline)';
return 'Task(id: $id, title: $title, description: $description, isCompleted: $isCompleted, deadline: $deadline, color: $color, recurringDays: $recurringDays, reminder: $reminder)';
}
}
8 changes: 8 additions & 0 deletions lib/screens/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import 'package:taskly/screens/tasklist_screen.dart';
import 'package:taskly/models/task.dart';
import 'package:taskly/storage/task_storage.dart';
import 'package:taskly/service/random_tip_service.dart';
import 'package:taskly/widgets/email_reminder_card.dart';
import 'package:taskly/widgets/theme_mode_switch.dart';
import 'package:taskly/widgets/tip_of_day_card.dart';
import 'dart:io';
Expand Down Expand Up @@ -189,6 +190,9 @@ class _HomeScreenState extends State<HomeScreen> {
showtip = !showtip;
} else if (option == TaskOption.exportToCSV) {
exportToCSV(tasks);
} else if (option == TaskOption.emailReminders) {
showDialog(
context: context, builder: (context) => const EmailReminderCard());
}
});
void _editTask(int index) async {
Expand Down Expand Up @@ -347,6 +351,10 @@ class _HomeScreenState extends State<HomeScreen> {
value: TaskOption.launchMeditationScreen,
child: Text("Meditate"),
),
const PopupMenuItem(
value: TaskOption.emailReminders,
child: Text("Email Reminders"),
),
];
},
),
Expand Down
Loading