Skip to content

Commit

Permalink
Merge pull request #8 from JobinBiju/beta
Browse files Browse the repository at this point in the history
Added more features. fixes #7
  • Loading branch information
JobinBiju authored Apr 19, 2021
2 parents e1f32e9 + 2df0e7d commit 6b66c50
Show file tree
Hide file tree
Showing 12 changed files with 317 additions and 71 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ samples, guidance on mobile development, and a full API reference.
- Option to repeat tasks daily.
- Drink Water Notification feature that display a notification to drink water once every hour
- Fast, Compact & Easy to Use
- #### What's New
- Added task notification.
- Seperated old notification from All Tasks screen.
- Fixed bug in upcoming tasks.

# App UI

Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<application
android:name="io.flutter.app.FlutterApplication"
Expand Down
66 changes: 52 additions & 14 deletions lib/app/data/services/notification_service.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:get/get.dart';
import 'package:taskly/app/data/model/task_model.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

class NotificationPlugin {
// Notification controller
Expand All @@ -18,15 +22,12 @@ class NotificationPlugin {
}

Future showNotification() async {
//var scheduledTime = DateTime.now().add(Duration(seconds: 5));

var androidDetails = AndroidNotificationDetails(
'Channel ID 0',
'Drink Water',
'Drink Water Notification',
importance: Importance.max,
priority: Priority.high,
timeoutAfter: 3000,
sound: RawResourceAndroidNotificationSound('slow_spring_board'),
enableLights: true,
enableVibration: true,
Expand All @@ -42,29 +43,66 @@ class NotificationPlugin {

// Function to periodically show notification
await fNotification.periodicallyShow(
1,
10001,
'Drink Water',
'Keep Yourself Hydrated',
RepeatInterval.hourly,
generalNotificationDetails,
payload: "Tasks",
payload: "Drink Water",
androidAllowWhileIdle: true,
);
}

Future cancelDrinkwaterNotifucation() async {
await fNotification.cancel(10001);
}

Future showTaskNotification(Task task, int id) async {
final String currentTimeZone =
await FlutterNativeTimezone.getLocalTimezone();
final location = tz.getLocation(currentTimeZone);
var scheduledTime = tz.TZDateTime.from(task.taskDate, location)
.add(const Duration(seconds: 5));

var androidDetails = AndroidNotificationDetails(
"Channel ID 2",
task.taskTitle,
task.taskDesc,
importance: Importance.max,
priority: Priority.high,
sound: RawResourceAndroidNotificationSound('slow_spring_board'),
enableLights: true,
enableVibration: true,
ledColor: Color.fromARGB(255, 255, 0, 255),
ledOnMs: 1000,
ledOffMs: 500,
);
var iOSDetails = IOSNotificationDetails();
var generalNotificationDetails = NotificationDetails(
android: androidDetails,
iOS: iOSDetails,
);

// await fNotification.schedule(
// 1,
// "Drink",
// "Drink Water",
// scheduledTime,
// generalNotificationDetails,
// );
await fNotification.zonedSchedule(
id,
task.taskTitle,
task.taskDesc,
scheduledTime,
generalNotificationDetails,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime,
androidAllowWhileIdle: true,
payload: task.taskTitle,
matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
);
}

Future onCancelNotifucation() async {
await fNotification.cancel(1);
Future cancelTaskNotifucation(int id) async {
await fNotification.cancel(id);
}

void init() {
tz.initializeTimeZones();
// notification config
fNotification = FlutterLocalNotificationsPlugin();
var androidInitialize = AndroidInitializationSettings('app_icon');
Expand Down
36 changes: 18 additions & 18 deletions lib/app/data/services/time_zone.dart
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
// import 'package:timezone/data/latest.dart';
// import 'package:timezone/timezone.dart' as t;
// import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

// class TimeZone {
// factory TimeZone() => _this ?? TimeZone._();
class TimeZone {
factory TimeZone() => _this ?? TimeZone._();

// TimeZone._() {
// initializeTimeZones();
// }
// static TimeZone _this;
TimeZone._() {
tz.initializeTimeZones();
}
static TimeZone _this;

// Future<String> getTimeZoneName() async =>
// FlutterNativeTimezone.getLocalTimezone();
Future<String> getTimeZoneName() async =>
FlutterNativeTimezone.getLocalTimezone();

// Future<t.Location> getLocation([String timeZoneName]) async {
// if (timeZoneName == null || timeZoneName.isEmpty) {
// timeZoneName = await getTimeZoneName();
// }
// return t.getLocation(timeZoneName);
// }
// }
Future<tz.Location> getLocation([String timeZoneName]) async {
if (timeZoneName == null || timeZoneName.isEmpty) {
timeZoneName = await getTimeZoneName();
}
return tz.getLocation(timeZoneName);
}
}
77 changes: 57 additions & 20 deletions lib/app/modules/home/controllers/home_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:get_storage/get_storage.dart';
import 'package:hive/hive.dart';
import 'package:path_provider/path_provider.dart';
import 'package:taskly/app/data/model/task_model.dart';
import 'package:taskly/app/data/services/notification_service.dart';
import 'package:taskly/app/modules/home/views/dashboard_view.dart';
import 'package:taskly/app/modules/home/views/today_task_view.dart';
import 'package:intl/intl.dart';
Expand Down Expand Up @@ -73,12 +74,17 @@ class HomeController extends GetxController {

// task lists
List<Task> allTasks = [];
List<Task> commingTasks = [];
List<Task> pastTasks = [];
List<Task> todayTasks = [];

// userData
String userName;
bool isMale = false;

// instance of notification Plugin
NotificationPlugin nPlugin;

// function to return correct view on bottom navBar switch
Widget navBarSwitcher() {
return homeViews.elementAt(currentIndex);
Expand Down Expand Up @@ -125,6 +131,17 @@ class HomeController extends GetxController {
var bD = b.taskDate.toString();
return aD.compareTo(bD);
});
pastTasks.clear();
commingTasks.clear();
List<Task> tmpPastTasks = [];
allTasks.forEach((element) {
if (element.taskDate.isBefore(currDt)) {
tmpPastTasks.add(element);
} else {
commingTasks.add(element);
}
});
pastTasks = tmpPastTasks.reversed.toList();
}

// Function to generate dailyTask
Expand Down Expand Up @@ -177,10 +194,7 @@ class HomeController extends GetxController {
taskIds = idOfTask;
Hive.close();
controllerReset();
sortAllTasks();
dailyTask();
setCurrentTask();
setUpcomingTask();
taskRoutine();
update([1, true]);
Get.back();
}
Expand Down Expand Up @@ -219,11 +233,8 @@ class HomeController extends GetxController {
tempTask.isRepeat = isRepeat;
int index = allTasks.indexOf(task);
allTasks.setAll(index, [tempTask]);
sortAllTasks();
taskRoutine();
reWriteTasks();
dailyTask();
setCurrentTask();
setUpcomingTask();
update([1, true]);
Get.back();
print(index);
Expand Down Expand Up @@ -252,11 +263,8 @@ class HomeController extends GetxController {
deleteTask(Task task) async {
int index = allTasks.indexOf(task);
allTasks.removeAt(index);
sortAllTasks();
taskRoutine();
reWriteTasks();
dailyTask();
setCurrentTask();
setUpcomingTask();
update([1, true]);
print(index);
}
Expand Down Expand Up @@ -289,6 +297,16 @@ class HomeController extends GetxController {
isRepeat = false;
}

// function to do routine on CRUD operations
taskRoutine() {
sortAllTasks();
dailyTask();
setCurrentTask();
setUpcomingTask();
cancellAllTaskNotification();
setTaskNotification();
}

// setDateFunction bottomSheet
Future<Null> selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
Expand Down Expand Up @@ -362,12 +380,17 @@ class HomeController extends GetxController {
// function to set upcomingTask
setUpcomingTask() {
isUpcommingTaskPresent = false;
upcomingTask = Task();
var cDt = DateTime.now();
if (todayTasks.length != 0) {
for (int i = 0; i < todayTasks.length - 1; i++) {
if (todayTasks[i + 1].taskDate.isAfter(cDt)) {
var index = todayTasks.indexOf(currentTask);
upcomingTask = todayTasks.elementAt(index + 1);
for (int i = 0; i < todayTasks.length; i++) {
if (todayTasks[i].taskDate.compareTo(cDt) > 0) {
if (isCurrentTaskPresent) {
var index = todayTasks.indexOf(currentTask);
upcomingTask = todayTasks.elementAt(index + 1);
} else {
upcomingTask = todayTasks.first;
}
isUpcommingTaskPresent = true;
break;
}
Expand All @@ -383,17 +406,31 @@ class HomeController extends GetxController {
update([7, true]);
}

// function to set notifications for tasks.
setTaskNotification() {
allTasks.forEach((element) {
if (element.taskDate.isAfter(DateTime.now())) {
nPlugin.showTaskNotification(element, allTasks.indexOf(element));
}
});
}

// function to cancel notifications for tasks.
cancellAllTaskNotification() {
allTasks.forEach((element) {
nPlugin.cancelTaskNotifucation(allTasks.indexOf(element));
});
}

@override
void onInit() async {
super.onInit();
Directory appDocDir = await getApplicationDocumentsDirectory();
Hive.init(appDocDir.path);
nPlugin = NotificationPlugin();
allTasks = await getTasks();
sortAllTasks();
taskRoutine();
reWriteTasks();
dailyTask();
setCurrentTask();
setUpcomingTask();
update([1, true]);
titleController = TextEditingController();
descController = TextEditingController();
Expand Down
29 changes: 23 additions & 6 deletions lib/app/modules/home/views/all_tasks_view.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';

import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:taskly/app/global_widgets/bottom_sheet.dart';
import 'package:taskly/app/global_widgets/expandable_container.dart';
import 'package:taskly/app/modules/home/controllers/home_controller.dart';
import 'package:taskly/app/modules/home/views/past_tasks_view.dart';
import 'package:taskly/app/theme/text_theme.dart';

class AllTasksView extends GetView<HomeController> {
Expand All @@ -22,10 +24,25 @@ class AllTasksView extends GetView<HomeController> {
children: [
Padding(
padding: EdgeInsets.only(top: 50, left: 25, right: 25),
child: Text(
'All Tasks',
style: kSubHeadTextStyle.copyWith(
color: Theme.of(context).primaryColorDark),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'All Tasks',
style: kSubHeadTextStyle.copyWith(
color: Theme.of(context).primaryColorDark),
),
IconButton(
icon: Icon(
FontAwesomeIcons.history,
color: Theme.of(context).primaryColor,
size: 24,
),
onPressed: () {
Get.to(() => PastTasksView());
},
),
],
),
),
SizedBox(height: Get.height * 0.012),
Expand All @@ -35,7 +52,7 @@ class AllTasksView extends GetView<HomeController> {
return Expanded(
child: ListView.builder(
itemBuilder: (context, index) {
final task = controller.allTasks[index];
final task = controller.commingTasks[index];
return Slidable(
actionPane: SlidableBehindActionPane(),
actionExtentRatio: 0.2,
Expand Down Expand Up @@ -115,7 +132,7 @@ class AllTasksView extends GetView<HomeController> {
],
);
},
itemCount: controller.allTasks.length,
itemCount: controller.commingTasks.length,
),
);
},
Expand Down
Loading

0 comments on commit 6b66c50

Please sign in to comment.