From a8c5361452c1c4c7d2e7c53d024da44342ac538e Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Thu, 18 Nov 2021 23:01:53 +0530 Subject: [PATCH 1/8] Add Due Date Time field to AddTaskScreen.kt --- .../dev/spikeysanju/einsen/components/TextInput.kt | 2 ++ .../dev/spikeysanju/einsen/view/add/AddTaskScreen.kt | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt b/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt index 080d853..9979cdb 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt @@ -69,6 +69,7 @@ fun EinsenInputTextField( modifier: Modifier = Modifier, title: String, value: String, + readOnly: Boolean = false, onValueChanged: (String) -> Unit ) { var textState by rememberSaveable { mutableStateOf("") } @@ -83,6 +84,7 @@ fun EinsenInputTextField( .fillMaxWidth() .padding(start = 20.dp, end = 20.dp), value = value, + readOnly = readOnly, onValueChange = { textState = it when (textState.isEmpty()) { diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt index 6da5233..08a3bea 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt @@ -213,6 +213,18 @@ fun AddTaskScreen( } } + // Due Date Time + item { + Spacer(modifier = modifier.height(24.dp)) + EinsenInputTextField( + title = stringResource(R.string.text_category), + value = taskState.category, + readOnly = true + ) { + taskState = taskState.copy(category = it) + } + } + val titleStyle = TextStyle( fontSize = 16.sp, fontFamily = Sailec, From e12978129adb63796b6ce2c66e88a8c234a6b706 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sat, 20 Nov 2021 11:41:34 +0530 Subject: [PATCH 2/8] Extend MainActivity.kt from AppCompatActivity to Show material date and time picker --- .../dev/spikeysanju/einsen/MainActivity.kt | 3 +- .../einsen/components/DatePicker.kt | 70 +++++++++++++++++++ .../einsen/components/TextInput.kt | 2 + .../einsen/utils/DateTimeHelper.kt | 28 ++++++++ .../einsen/view/add/AddTaskScreen.kt | 33 +++++++-- app/src/main/res/values/strings.xml | 1 + 6 files changed, 130 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt create mode 100644 app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt diff --git a/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt b/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt index 7bf4d28..8a4fc69 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt @@ -22,6 +22,7 @@ package dev.spikeysanju.einsen import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material.Surface @@ -42,7 +43,7 @@ import kotlinx.coroutines.launch import javax.inject.Inject @AndroidEntryPoint -class MainActivity : ComponentActivity() { +class MainActivity : AppCompatActivity() { @Inject lateinit var themeManager: ThemeManager diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt new file mode 100644 index 0000000..054e269 --- /dev/null +++ b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt @@ -0,0 +1,70 @@ +/* + * + * * Copyright 2021 Spikey Sanju + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + * + */ + +package dev.spikeysanju.einsen.components + +import android.content.Context +import androidx.fragment.app.FragmentActivity +import com.google.android.material.datepicker.MaterialDatePicker +import com.google.android.material.timepicker.MaterialTimePicker +import java.util.* + + +fun Context?.showDatePicker( + defaultCalendar: Calendar, + onDismiss: (() -> Unit)? = null, + onDateSelect: (Calendar) -> Unit +) { + (this as? FragmentActivity)?.supportFragmentManager?.let { manager -> + val builder = MaterialDatePicker.Builder.datePicker() + .setSelection(defaultCalendar.timeInMillis) + .build() + builder.addOnPositiveButtonClickListener { selectedDate -> + val newCal = Calendar.getInstance() + newCal.timeInMillis = selectedDate + onDateSelect.invoke(newCal) + } + builder.addOnDismissListener { + onDismiss?.invoke() + } + builder.show(manager, "DatePicker") + } +} + +fun Context?.showTimePicker( + defaultCalendar: Calendar, + onDismiss: (() -> Unit)? = null, + onTimeSelected: (Calendar) -> Unit +) { + (this as? FragmentActivity)?.supportFragmentManager?.let { manager -> + val builder = MaterialTimePicker.Builder() + .setHour(defaultCalendar.get(Calendar.HOUR_OF_DAY)) + .setMinute(defaultCalendar.get(Calendar.MINUTE)) + .build() + builder.addOnPositiveButtonClickListener { + defaultCalendar.set(Calendar.HOUR_OF_DAY, builder.hour) + defaultCalendar.set(Calendar.MINUTE, builder.minute) + onTimeSelected.invoke(defaultCalendar) + } + builder.addOnDismissListener { + onDismiss?.invoke() + } + builder.show(manager, "TimePicker") + } +} diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt b/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt index 9979cdb..99748bf 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/TextInput.kt @@ -70,6 +70,7 @@ fun EinsenInputTextField( title: String, value: String, readOnly: Boolean = false, + enabled: Boolean = true, onValueChanged: (String) -> Unit ) { var textState by rememberSaveable { mutableStateOf("") } @@ -85,6 +86,7 @@ fun EinsenInputTextField( .padding(start = 20.dp, end = 20.dp), value = value, readOnly = readOnly, + enabled = enabled, onValueChange = { textState = it when (textState.isEmpty()) { diff --git a/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt b/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt new file mode 100644 index 0000000..4e1c6cb --- /dev/null +++ b/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt @@ -0,0 +1,28 @@ +/* + * + * * Copyright 2021 Spikey Sanju + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + * + */ + +package dev.spikeysanju.einsen.utils + +import java.text.SimpleDateFormat +import java.util.* + +fun formatCalendar(calendar: java.util.Calendar, dateTimeFormat: String?): String { + val simpleDateFormat = SimpleDateFormat(dateTimeFormat, Locale.getDefault()) + return simpleDateFormat.format(calendar.time) +} diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt index 08a3bea..088dde8 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt @@ -19,6 +19,9 @@ package dev.spikeysanju.einsen.view.add +import androidx.activity.ComponentActivity +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -54,12 +57,21 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.os.bundleOf +import androidx.fragment.app.FragmentActivity +import androidx.navigation.NavHost +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.google.android.material.datepicker.MaterialDatePicker import com.google.firebase.analytics.FirebaseAnalytics +import dev.spikeysanju.einsen.MainActivity import dev.spikeysanju.einsen.R import dev.spikeysanju.einsen.components.EinsenInputTextField import dev.spikeysanju.einsen.components.EinsenStepSlider import dev.spikeysanju.einsen.components.EmojiPlaceHolder import dev.spikeysanju.einsen.components.PrimaryButton +import dev.spikeysanju.einsen.components.showDatePicker +import dev.spikeysanju.einsen.components.showTimePicker import dev.spikeysanju.einsen.model.task.Priority import dev.spikeysanju.einsen.model.task.task import dev.spikeysanju.einsen.navigation.MainActions @@ -67,9 +79,11 @@ import dev.spikeysanju.einsen.ui.theme.Sailec import dev.spikeysanju.einsen.ui.theme.einsenColors import dev.spikeysanju.einsen.ui.theme.typography import dev.spikeysanju.einsen.utils.calculatePriority +import dev.spikeysanju.einsen.utils.formatCalendar import dev.spikeysanju.einsen.utils.showToast import dev.spikeysanju.einsen.view.viewmodel.MainViewModel import kotlinx.coroutines.launch +import java.util.* @Composable fun AddTaskScreen( @@ -213,16 +227,23 @@ fun AddTaskScreen( } } + // Due Date Time item { Spacer(modifier = modifier.height(24.dp)) EinsenInputTextField( - title = stringResource(R.string.text_category), - value = taskState.category, - readOnly = true - ) { - taskState = taskState.copy(category = it) - } + modifier = Modifier.clickable { + val calendar = Calendar.getInstance() + context.showDatePicker(calendar){ + context.showTimePicker(it){ timeCalendar -> + taskState = taskState.copy(due = formatCalendar(timeCalendar, "dd MM yyyy hh:mm aa")) + } + } + }, + title = stringResource(R.string.text_due_date_time), + value = taskState.due, + readOnly = true, enabled = false, {} + ) } val titleStyle = TextStyle( diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a450948..6b2c70d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -56,6 +56,7 @@ Title Description Category + Due Date Time Importance Save Task Urgency From e4216a7f1beab6c6e7ae6144791f5d92a7fd59f6 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sat, 20 Nov 2021 12:03:26 +0530 Subject: [PATCH 3/8] Add Date Picker Constraint and Validator to prevent past date selection --- .../einsen/components/DatePicker.kt | 9 +++ .../einsen/utils/DateTimeHelper.kt | 18 ++++- .../spikeysanju/einsen/utils/DateValidator.kt | 69 +++++++++++++++++++ .../einsen/view/add/AddTaskScreen.kt | 23 +++---- 4 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt index 054e269..13168b0 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt @@ -21,18 +21,27 @@ package dev.spikeysanju.einsen.components import android.content.Context import androidx.fragment.app.FragmentActivity +import com.google.android.material.datepicker.CalendarConstraints import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.timepicker.MaterialTimePicker +import dev.spikeysanju.einsen.utils.DateValidator import java.util.* fun Context?.showDatePicker( defaultCalendar: Calendar, onDismiss: (() -> Unit)? = null, + minDate: Long = System.currentTimeMillis(), onDateSelect: (Calendar) -> Unit ) { (this as? FragmentActivity)?.supportFragmentManager?.let { manager -> + + val calendarConstraints = CalendarConstraints.Builder().setStart(minDate) + .setValidator(DateValidator(minDate)) + .build() + val builder = MaterialDatePicker.Builder.datePicker() + .setCalendarConstraints(calendarConstraints) .setSelection(defaultCalendar.timeInMillis) .build() builder.addOnPositiveButtonClickListener { selectedDate -> diff --git a/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt b/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt index 4e1c6cb..aeaaab7 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt @@ -19,10 +19,26 @@ package dev.spikeysanju.einsen.utils +import java.text.ParseException import java.text.SimpleDateFormat import java.util.* -fun formatCalendar(calendar: java.util.Calendar, dateTimeFormat: String?): String { +const val DUE_DATE_FORMAT = "dd MMM yyyy hh:mm aa" + +fun formatCalendar(calendar: Calendar, dateTimeFormat: String? = DUE_DATE_FORMAT): String { val simpleDateFormat = SimpleDateFormat(dateTimeFormat, Locale.getDefault()) return simpleDateFormat.format(calendar.time) } + +fun getCalendar(dateTime: String): Calendar { + val simpleDateFormat = SimpleDateFormat(DUE_DATE_FORMAT, Locale.getDefault()) + val cal = Calendar.getInstance() + try { + simpleDateFormat.parse(dateTime)?.let { + cal.time = it + } + } catch (e: ParseException) { + e.printStackTrace() + } + return cal +} diff --git a/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt b/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt new file mode 100644 index 0000000..0a9afd5 --- /dev/null +++ b/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt @@ -0,0 +1,69 @@ +/* + * + * * Copyright 2021 Spikey Sanju + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + * + */ + +package dev.spikeysanju.einsen.utils + +import android.os.Parcel +import android.os.Parcelable +import com.google.android.material.datepicker.CalendarConstraints + +class DateValidator() : CalendarConstraints.DateValidator { + var startDate: Long = -1 + var endDate: Long = -1 + + constructor(startDate: Long = -1, endDate: Long = -1) : this() { + this.startDate = startDate + this.endDate = endDate + } + + constructor(parcel: Parcel) : this() { + startDate = parcel.readLong() + endDate = parcel.readLong() + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeLong(startDate) + parcel.writeLong(endDate) + } + + override fun isValid(date: Long): Boolean { + return if (startDate != -1L && endDate != -1L && date in startDate..endDate) { + // valid date between start and end date + true + } else if (startDate == -1L && date < endDate) { + true + } else endDate == -1L && date >= startDate + } + + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): DateValidator { + return DateValidator(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } + +} diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt index 088dde8..6f15c5f 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt @@ -19,8 +19,6 @@ package dev.spikeysanju.einsen.view.add -import androidx.activity.ComponentActivity -import androidx.appcompat.app.AppCompatActivity import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -57,14 +55,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.os.bundleOf -import androidx.fragment.app.FragmentActivity -import androidx.navigation.NavHost -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController -import com.google.android.material.datepicker.MaterialDatePicker import com.google.firebase.analytics.FirebaseAnalytics -import dev.spikeysanju.einsen.MainActivity import dev.spikeysanju.einsen.R import dev.spikeysanju.einsen.components.EinsenInputTextField import dev.spikeysanju.einsen.components.EinsenStepSlider @@ -80,6 +71,7 @@ import dev.spikeysanju.einsen.ui.theme.einsenColors import dev.spikeysanju.einsen.ui.theme.typography import dev.spikeysanju.einsen.utils.calculatePriority import dev.spikeysanju.einsen.utils.formatCalendar +import dev.spikeysanju.einsen.utils.getCalendar import dev.spikeysanju.einsen.utils.showToast import dev.spikeysanju.einsen.view.viewmodel.MainViewModel import kotlinx.coroutines.launch @@ -114,7 +106,7 @@ fun AddTaskScreen( urgency = defaultUrgency importance = defaultImportance priority = Priority.IMPORTANT - due = "18/12/1998" + due = "" isCompleted = false } ) @@ -233,10 +225,13 @@ fun AddTaskScreen( Spacer(modifier = modifier.height(24.dp)) EinsenInputTextField( modifier = Modifier.clickable { - val calendar = Calendar.getInstance() - context.showDatePicker(calendar){ - context.showTimePicker(it){ timeCalendar -> - taskState = taskState.copy(due = formatCalendar(timeCalendar, "dd MM yyyy hh:mm aa")) + val calendar = getCalendar(taskState.due) + context.showDatePicker(calendar) { + calendar.set(Calendar.DAY_OF_MONTH, it.get(Calendar.DAY_OF_MONTH)) + calendar.set(Calendar.MONTH, it.get(Calendar.MONTH)) + calendar.set(Calendar.YEAR, it.get(Calendar.YEAR)) + context.showTimePicker(calendar) { timeCalendar -> + taskState = taskState.copy(due = formatCalendar(timeCalendar)) } } }, From 28fc028f30642ce7204f8e6c53e22af11944b7d4 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sat, 20 Nov 2021 20:07:29 +0530 Subject: [PATCH 4/8] Set theme for DatePicker and TimePicker --- .../einsen/components/DatePicker.kt | 5 +++ .../color/text_btn_text_color_selector.xml | 26 ++++++++++++++++ app/src/main/res/values/colors.xml | 5 +++ app/src/main/res/values/themes.xml | 31 +++++++++++++++++-- 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 app/src/main/res/color/text_btn_text_color_selector.xml diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt index 13168b0..83de704 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt @@ -20,10 +20,13 @@ package dev.spikeysanju.einsen.components import android.content.Context +import androidx.appcompat.view.ContextThemeWrapper +import androidx.fragment.app.DialogFragment.STYLE_NORMAL import androidx.fragment.app.FragmentActivity import com.google.android.material.datepicker.CalendarConstraints import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.timepicker.MaterialTimePicker +import dev.spikeysanju.einsen.R import dev.spikeysanju.einsen.utils.DateValidator import java.util.* @@ -41,9 +44,11 @@ fun Context?.showDatePicker( .build() val builder = MaterialDatePicker.Builder.datePicker() + .setTheme(R.style.ThemeOverlay_App_DatePicker) .setCalendarConstraints(calendarConstraints) .setSelection(defaultCalendar.timeInMillis) .build() + builder.addOnPositiveButtonClickListener { selectedDate -> val newCal = Calendar.getInstance() newCal.timeInMillis = selectedDate diff --git a/app/src/main/res/color/text_btn_text_color_selector.xml b/app/src/main/res/color/text_btn_text_color_selector.xml new file mode 100644 index 0000000..42111d0 --- /dev/null +++ b/app/src/main/res/color/text_btn_text_color_selector.xml @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 46f2783..a569cbd 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -25,4 +25,9 @@ #FF03DAC5 #FF000000 #FFFFFFFF + + #EEEEEE + #EEEEEE + #F4F4F4 + #F4F7FD diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 0bde567..1f1d991 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -24,9 +24,12 @@ false - @color/purple_500 - @color/purple_700 - @color/white + @color/white_100 + @color/white_200 + @color/black + @color/black + + @style/ThemeOverlay.App.TimePicker + + + + + + From ae191ac704204a8b9e0eaccf4036ba559d9f3427 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sat, 20 Nov 2021 21:05:53 +0530 Subject: [PATCH 5/8] Schedule worker for reminder --- .../dev/spikeysanju/einsen/model/task/Task.kt | 4 +- .../einsen/view/add/AddTaskScreen.kt | 3 +- .../einsen/workers/MyWorkManager.kt | 44 +++++++++++++++++++ .../einsen/workers/ReminderWorker.kt | 33 ++++++++++++++ 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt create mode 100644 app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt diff --git a/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt b/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt index 7dcc33f..396e05b 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt @@ -52,7 +52,9 @@ data class Task( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0 -) +){ + fun getWorkerId() = "reminder_$id" +} enum class Priority(count: Int) { URGENT(4), diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt index 6f15c5f..763e456 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt @@ -74,6 +74,7 @@ import dev.spikeysanju.einsen.utils.formatCalendar import dev.spikeysanju.einsen.utils.getCalendar import dev.spikeysanju.einsen.utils.showToast import dev.spikeysanju.einsen.view.viewmodel.MainViewModel +import dev.spikeysanju.einsen.workers.scheduleReminders import kotlinx.coroutines.launch import java.util.* @@ -298,7 +299,7 @@ fun AddTaskScreen( } else -> { viewModel.insertTask(taskState).run { - + context.scheduleReminders(taskState) showToast(context, "Task added successfully") // log event to firebase diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt new file mode 100644 index 0000000..72c86ef --- /dev/null +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt @@ -0,0 +1,44 @@ +/* + * + * * Copyright 2021 Spikey Sanju + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + * + */ + +package dev.spikeysanju.einsen.workers + +import android.content.Context +import androidx.work.ExistingWorkPolicy +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkManager +import dev.spikeysanju.einsen.model.task.Task +import dev.spikeysanju.einsen.utils.getCalendar +import java.util.* +import java.util.concurrent.TimeUnit + +fun Context.scheduleReminders(task: Task) { + val calendar = getCalendar(task.due) + val worker = OneTimeWorkRequest.Builder(ReminderWorker::class.java) + .setInitialDelay(calendar.timeInMillis - System.currentTimeMillis(), TimeUnit.MILLISECONDS) + .build() + WorkManager.getInstance(this) + .enqueueUniqueWork(task.getWorkerId(), ExistingWorkPolicy.KEEP, worker) +} + +fun Context.cancelReminder(task: Task) { + WorkManager.getInstance(this).cancelUniqueWork(task.getWorkerId()) +} + + diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt new file mode 100644 index 0000000..fd0261f --- /dev/null +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt @@ -0,0 +1,33 @@ +/* + * + * * Copyright 2021 Spikey Sanju + * * + * * Licensed under the Apache License, Version 2.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * https://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. + * + * + */ + +package dev.spikeysanju.einsen.workers + +import android.content.Context +import android.util.Log +import androidx.work.Worker +import androidx.work.WorkerParameters + +class ReminderWorker(context: Context, workerParams: WorkerParameters) : + Worker(context, workerParams) { + override fun doWork(): Result { + Log.d("ReminderWorker", "doWork: Called ${System.currentTimeMillis()}") + return Result.success() + } +} From 573e4c49b643c16daa033d615e4f8ac8691960bf Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sun, 21 Nov 2021 00:37:11 +0530 Subject: [PATCH 6/8] Worker Improvements Send Notification prior to 1 hour of task due date time --- app/build.gradle.kts | 3 + app/src/main/AndroidManifest.xml | 14 ++++ .../dev/spikeysanju/einsen/app/EinsenApp.kt | 12 +++- .../einsen/components/DatePicker.kt | 9 ++- .../einsen/data/local/db/TaskDao.kt | 3 + .../dev/spikeysanju/einsen/di/AppModule.kt | 7 ++ .../einsen/view/edit/EditTaskScreen.kt | 32 +++++++++- .../einsen/workers/MyWorkManager.kt | 23 +++++-- .../einsen/workers/ReminderWorker.kt | 64 +++++++++++++++++-- app/src/main/res/values/strings.xml | 5 ++ build.gradle.kts | 1 + 11 files changed, 156 insertions(+), 17 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a40de46..5e6f1c0 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -166,5 +166,8 @@ dependencies { // Square Logcat implementation("com.squareup.logcat:logcat:${rootProject.extra["logcatVersion"]}") + + // Worker + Coroutine + implementation("androidx.work:work-runtime-ktx:${rootProject.extra["workerVersion"]}") } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6cdb5c5..1873a75 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -19,6 +19,7 @@ --> @@ -43,6 +44,19 @@ + + + + + + diff --git a/app/src/main/java/dev/spikeysanju/einsen/app/EinsenApp.kt b/app/src/main/java/dev/spikeysanju/einsen/app/EinsenApp.kt index 875b020..eb26660 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/app/EinsenApp.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/app/EinsenApp.kt @@ -20,6 +20,8 @@ package dev.spikeysanju.einsen.app import android.app.Application +import androidx.hilt.work.HiltWorkerFactory +import androidx.work.Configuration import com.google.firebase.analytics.FirebaseAnalytics import dagger.hilt.android.HiltAndroidApp import logcat.AndroidLogcatLogger @@ -27,11 +29,19 @@ import logcat.LogPriority import javax.inject.Inject @HiltAndroidApp -class EinsenApp : Application() { +class EinsenApp : Application(), Configuration.Provider { @Inject lateinit var mFirebaseAnalytics: FirebaseAnalytics + @Inject + lateinit var workerFactory: HiltWorkerFactory + + override fun getWorkManagerConfiguration() = + Configuration.Builder() + .setWorkerFactory(workerFactory) + .build() + override fun onCreate() { super.onCreate() // Log all priorities in debug builds, no-op in release builds. diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt index 83de704..7cd7fc6 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt @@ -20,8 +20,6 @@ package dev.spikeysanju.einsen.components import android.content.Context -import androidx.appcompat.view.ContextThemeWrapper -import androidx.fragment.app.DialogFragment.STYLE_NORMAL import androidx.fragment.app.FragmentActivity import com.google.android.material.datepicker.CalendarConstraints import com.google.android.material.datepicker.MaterialDatePicker @@ -34,7 +32,12 @@ import java.util.* fun Context?.showDatePicker( defaultCalendar: Calendar, onDismiss: (() -> Unit)? = null, - minDate: Long = System.currentTimeMillis(), + minDate: Long = Calendar.getInstance().also { + it.set(Calendar.MINUTE, 0) + it.set(Calendar.HOUR_OF_DAY, 0) + it.set(Calendar.SECOND, 0) + it.set(Calendar.MILLISECOND, 0) + }.timeInMillis, onDateSelect: (Calendar) -> Unit ) { (this as? FragmentActivity)?.supportFragmentManager?.let { manager -> diff --git a/app/src/main/java/dev/spikeysanju/einsen/data/local/db/TaskDao.kt b/app/src/main/java/dev/spikeysanju/einsen/data/local/db/TaskDao.kt index d180aac..c15cde8 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/data/local/db/TaskDao.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/data/local/db/TaskDao.kt @@ -45,6 +45,9 @@ interface TaskDao { @Query("SELECT * FROM task where id=:id") fun findByID(id: Int): Flow + @Query("SELECT * FROM task where id=:id") + fun findTaskByID(id: Int): Task + @Query("UPDATE task set isCompleted= :isCompleted where id=:id") suspend fun updateTaskStatus(id: Int, isCompleted: Boolean) diff --git a/app/src/main/java/dev/spikeysanju/einsen/di/AppModule.kt b/app/src/main/java/dev/spikeysanju/einsen/di/AppModule.kt index 46e4d45..f9e09a1 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/di/AppModule.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/di/AppModule.kt @@ -19,6 +19,7 @@ package dev.spikeysanju.einsen.di +import android.app.NotificationManager import android.content.Context import androidx.room.Room import com.google.firebase.analytics.FirebaseAnalytics @@ -60,4 +61,10 @@ object AppModule { fun provideFirebaseAnalytics(@ApplicationContext context: Context): FirebaseAnalytics { return FirebaseAnalytics.getInstance(context) } + + @Singleton + @Provides + fun provideNotificationManager(@ApplicationContext context: Context): NotificationManager { + return context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager + } } diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt index 1f0936c..c572e85 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt @@ -19,6 +19,7 @@ package dev.spikeysanju.einsen.view.edit +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues @@ -61,6 +62,8 @@ import dev.spikeysanju.einsen.components.EinsenInputTextField import dev.spikeysanju.einsen.components.EinsenStepSlider import dev.spikeysanju.einsen.components.EmojiPlaceHolder import dev.spikeysanju.einsen.components.PrimaryButton +import dev.spikeysanju.einsen.components.showDatePicker +import dev.spikeysanju.einsen.components.showTimePicker import dev.spikeysanju.einsen.model.task.Priority import dev.spikeysanju.einsen.model.task.task import dev.spikeysanju.einsen.navigation.MainActions @@ -68,12 +71,16 @@ import dev.spikeysanju.einsen.ui.theme.Sailec import dev.spikeysanju.einsen.ui.theme.einsenColors import dev.spikeysanju.einsen.ui.theme.typography import dev.spikeysanju.einsen.utils.calculatePriority +import dev.spikeysanju.einsen.utils.formatCalendar +import dev.spikeysanju.einsen.utils.getCalendar import dev.spikeysanju.einsen.utils.showToast import dev.spikeysanju.einsen.utils.viewstate.SingleViewState import dev.spikeysanju.einsen.view.animationviewstate.AnimationViewState import dev.spikeysanju.einsen.view.animationviewstate.ScreenState import dev.spikeysanju.einsen.view.viewmodel.MainViewModel +import dev.spikeysanju.einsen.workers.scheduleReminders import kotlinx.coroutines.launch +import java.util.* @Composable fun EditTaskScreen(modifier: Modifier, viewModel: MainViewModel, actions: MainActions) { @@ -97,7 +104,7 @@ fun EditTaskScreen(modifier: Modifier, viewModel: MainViewModel, actions: MainAc var emojiState by remember { mutableStateOf("") } var urgencyState by remember { mutableStateOf(0) } var importanceState by remember { mutableStateOf(0) } - var dueState by remember { mutableStateOf("18/12/1998") } + var dueState by remember { mutableStateOf("") } var priorityState by remember { mutableStateOf(Priority.IMPORTANT) } var isCompletedState by remember { mutableStateOf(false) } var createdAtState by remember { mutableStateOf(0L) } @@ -286,6 +293,28 @@ fun EditTaskScreen(modifier: Modifier, viewModel: MainViewModel, actions: MainAc } } + + // Due Date Time + item { + Spacer(modifier = modifier.height(24.dp)) + EinsenInputTextField( + modifier = Modifier.clickable { + val calendar = getCalendar(dueState) + context.showDatePicker(calendar) { + calendar.set(Calendar.DAY_OF_MONTH, it.get(Calendar.DAY_OF_MONTH)) + calendar.set(Calendar.MONTH, it.get(Calendar.MONTH)) + calendar.set(Calendar.YEAR, it.get(Calendar.YEAR)) + context.showTimePicker(calendar) { timeCalendar -> + dueState = formatCalendar(timeCalendar) + } + } + }, + title = stringResource(R.string.text_due_date_time), + value = dueState, + readOnly = true, enabled = false, {} + ) + } + val titleStyle = TextStyle( fontSize = 16.sp, fontFamily = Sailec, @@ -360,6 +389,7 @@ fun EditTaskScreen(modifier: Modifier, viewModel: MainViewModel, actions: MainAc else -> { viewModel.insertTask(task).run { + context.scheduleReminders(task) showToast(context, "Task updated successfully!") // log event to firebase val updateTaskBundle = bundleOf( diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt index 72c86ef..833f9d7 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt @@ -20,21 +20,32 @@ package dev.spikeysanju.einsen.workers import android.content.Context +import androidx.work.Data import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager import dev.spikeysanju.einsen.model.task.Task import dev.spikeysanju.einsen.utils.getCalendar -import java.util.* import java.util.concurrent.TimeUnit fun Context.scheduleReminders(task: Task) { val calendar = getCalendar(task.due) - val worker = OneTimeWorkRequest.Builder(ReminderWorker::class.java) - .setInitialDelay(calendar.timeInMillis - System.currentTimeMillis(), TimeUnit.MILLISECONDS) - .build() - WorkManager.getInstance(this) - .enqueueUniqueWork(task.getWorkerId(), ExistingWorkPolicy.KEEP, worker) + val initialDelay = + (calendar.timeInMillis - TimeUnit.HOURS.toMillis(1)) - System.currentTimeMillis() + if (initialDelay > 0) { + val data = Data.Builder() + .putInt(ARG_ID, task.id) + .build() + + val worker = OneTimeWorkRequest.Builder(ReminderWorker::class.java) + .setInitialDelay(initialDelay, TimeUnit.MILLISECONDS) + .setInputData(data) + .build() + WorkManager.getInstance(this) + .enqueueUniqueWork(task.getWorkerId(), ExistingWorkPolicy.REPLACE, worker) + } else { + cancelReminder(task) + } } fun Context.cancelReminder(task: Task) { diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt index fd0261f..0c46040 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt @@ -19,15 +19,67 @@ package dev.spikeysanju.einsen.workers +import android.app.NotificationChannel +import android.app.NotificationManager import android.content.Context -import android.util.Log -import androidx.work.Worker +import android.os.Build +import androidx.core.app.NotificationCompat +import androidx.hilt.work.HiltWorker +import androidx.work.CoroutineWorker import androidx.work.WorkerParameters +import dagger.assisted.Assisted +import dagger.assisted.AssistedInject +import dev.spikeysanju.einsen.R +import dev.spikeysanju.einsen.data.local.db.TaskDao +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.single +import kotlinx.coroutines.withContext -class ReminderWorker(context: Context, workerParams: WorkerParameters) : - Worker(context, workerParams) { - override fun doWork(): Result { - Log.d("ReminderWorker", "doWork: Called ${System.currentTimeMillis()}") +const val ARG_ID = "arg_id" + +@HiltWorker +class ReminderWorker @AssistedInject constructor( + @Assisted val context: Context, + @Assisted val workerParams: WorkerParameters, + private val taskDao: TaskDao, + private val notificationManager: NotificationManager +) : + CoroutineWorker(context, workerParams) { + override suspend fun doWork(): Result { + val reminderId = workerParams.inputData.getInt(ARG_ID, -1) + if (reminderId == -1) { + return Result.failure() + } + + withContext(Dispatchers.IO) { + + val task = taskDao.findTaskByID(reminderId) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channel = NotificationChannel( + context.getString(R.string.reminder_channel_id), + context.getString(R.string.reminder_channel_name), + NotificationManager.IMPORTANCE_HIGH, + ) + channel.lockscreenVisibility = NotificationCompat.VISIBILITY_PUBLIC + channel.enableVibration(true) + channel.setBypassDnd(true) + notificationManager.createNotificationChannel(channel) + } + + val builder = + NotificationCompat.Builder(context, context.getString(R.string.reminder_channel_id)) + builder.setContentTitle(task.title) + builder.setSmallIcon(R.drawable.einsen_logo) + builder.setCategory(NotificationCompat.CATEGORY_ALARM) + builder.setContentText("Task due time in 1 hour") + builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + builder.priority = NotificationCompat.PRIORITY_MAX + builder.setAutoCancel(true) + + notificationManager.notify(task.id, builder.build()) + + } return Result.success() } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6b2c70d..5967df3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -83,4 +83,9 @@ Go Back! Retry Search + + + reminders + Reminders + diff --git a/build.gradle.kts b/build.gradle.kts index fce874f..9f56beb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -27,6 +27,7 @@ buildscript { val composeNavigationVersion by extra("2.4.0-alpha03") val hiltComposeNavVersion by extra("1.0.0-alpha03") val hiltVersion by extra("2.37") + val workerVersion by extra("2.7.1") val hiltAndroidXVersion by extra("1.0.0-alpha03") val roomVersion by extra("2.3.0") val dataStoreVersion by extra("1.0.0-beta02") From e0b21c60a43c0837d24eba204e6353c9a56180ff Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sun, 21 Nov 2021 00:39:11 +0530 Subject: [PATCH 7/8] Cancel Reminder on Delete Task --- .../dev/spikeysanju/einsen/view/details/TaskDetailScreen.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/details/TaskDetailScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/details/TaskDetailScreen.kt index c98e741..fcf4c2f 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/details/TaskDetailScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/details/TaskDetailScreen.kt @@ -75,6 +75,7 @@ import dev.spikeysanju.einsen.utils.viewstate.SingleViewState import dev.spikeysanju.einsen.view.animationviewstate.AnimationViewState import dev.spikeysanju.einsen.view.animationviewstate.ScreenState import dev.spikeysanju.einsen.view.viewmodel.MainViewModel +import dev.spikeysanju.einsen.workers.cancelReminder import java.util.* @Composable @@ -84,6 +85,8 @@ fun TaskDetailsScreen( action: MainActions ) { + val context = LocalContext.current + LaunchedEffect(key1 = Unit) { // log event to firebase val taskDetailsComposableBundle = bundleOf( @@ -169,6 +172,7 @@ fun TaskDetailsScreen( }, onDelete = { viewModel.deleteTaskByID(taskState.id).run { + context.cancelReminder(taskState) action.upPress.invoke().run { // log event to firebase val deleteTaskBundle = bundleOf( From b621bfbc31f87c64ba855b992a1d919166e6a585 Mon Sep 17 00:00:00 2001 From: Yogesh Choudhary Paliyal Date: Sun, 21 Nov 2021 00:40:04 +0530 Subject: [PATCH 8/8] Spotless Code formatting --- app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt | 1 - .../main/java/dev/spikeysanju/einsen/components/DatePicker.kt | 1 - app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt | 2 +- app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt | 2 -- .../main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt | 1 - .../java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt | 1 - .../main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt | 2 -- .../main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt | 2 -- 8 files changed, 1 insertion(+), 11 deletions(-) diff --git a/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt b/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt index 8a4fc69..84d5c1a 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt @@ -20,7 +20,6 @@ package dev.spikeysanju.einsen import android.os.Bundle -import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate diff --git a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt index 7cd7fc6..1ae0126 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt @@ -28,7 +28,6 @@ import dev.spikeysanju.einsen.R import dev.spikeysanju.einsen.utils.DateValidator import java.util.* - fun Context?.showDatePicker( defaultCalendar: Calendar, onDismiss: (() -> Unit)? = null, diff --git a/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt b/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt index 396e05b..ca97aa2 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt @@ -52,7 +52,7 @@ data class Task( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Int = 0 -){ +) { fun getWorkerId() = "reminder_$id" } diff --git a/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt b/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt index 0a9afd5..d6ec523 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt @@ -51,7 +51,6 @@ class DateValidator() : CalendarConstraints.DateValidator { } else endDate == -1L && date >= startDate } - override fun describeContents(): Int { return 0 } @@ -65,5 +64,4 @@ class DateValidator() : CalendarConstraints.DateValidator { return arrayOfNulls(size) } } - } diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt index 763e456..106697f 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/add/AddTaskScreen.kt @@ -220,7 +220,6 @@ fun AddTaskScreen( } } - // Due Date Time item { Spacer(modifier = modifier.height(24.dp)) diff --git a/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt b/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt index c572e85..a5fd14a 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/view/edit/EditTaskScreen.kt @@ -293,7 +293,6 @@ fun EditTaskScreen(modifier: Modifier, viewModel: MainViewModel, actions: MainAc } } - // Due Date Time item { Spacer(modifier = modifier.height(24.dp)) diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt index 833f9d7..ee7d4ab 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/MyWorkManager.kt @@ -51,5 +51,3 @@ fun Context.scheduleReminders(task: Task) { fun Context.cancelReminder(task: Task) { WorkManager.getInstance(this).cancelUniqueWork(task.getWorkerId()) } - - diff --git a/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt index 0c46040..f47a406 100644 --- a/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt +++ b/app/src/main/java/dev/spikeysanju/einsen/workers/ReminderWorker.kt @@ -32,7 +32,6 @@ import dagger.assisted.AssistedInject import dev.spikeysanju.einsen.R import dev.spikeysanju.einsen.data.local.db.TaskDao import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.single import kotlinx.coroutines.withContext const val ARG_ID = "arg_id" @@ -78,7 +77,6 @@ class ReminderWorker @AssistedInject constructor( builder.setAutoCancel(true) notificationManager.notify(task.id, builder.build()) - } return Result.success() }