Skip to content

Commit

Permalink
Merge pull request #96 from yogeshpaliyal/feature/reminder
Browse files Browse the repository at this point in the history
Feature/reminder
  • Loading branch information
Spikeysanju committed Nov 21, 2021
2 parents 9ddeed7 + b621bfb commit d232dce
Show file tree
Hide file tree
Showing 21 changed files with 510 additions and 10 deletions.
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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"]}")
}

14 changes: 14 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="dev.spikeysanju.einsen">

<uses-permission android:name="android.permission.INTERNET" />
Expand All @@ -43,6 +44,19 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>

</application>

</manifest>
4 changes: 2 additions & 2 deletions app/src/main/java/dev/spikeysanju/einsen/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
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
Expand All @@ -42,7 +42,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
class MainActivity : AppCompatActivity() {
@Inject
lateinit var themeManager: ThemeManager

Expand Down
12 changes: 11 additions & 1 deletion app/src/main/java/dev/spikeysanju/einsen/app/EinsenApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,28 @@
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
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.
Expand Down
86 changes: 86 additions & 0 deletions app/src/main/java/dev/spikeysanju/einsen/components/DatePicker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
*
* * 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.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.*

fun Context?.showDatePicker(
defaultCalendar: Calendar,
onDismiss: (() -> Unit)? = null,
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 ->

val calendarConstraints = CalendarConstraints.Builder().setStart(minDate)
.setValidator(DateValidator(minDate))
.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
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")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ fun EinsenInputTextField(
modifier: Modifier = Modifier,
title: String,
value: String,
readOnly: Boolean = false,
enabled: Boolean = true,
onValueChanged: (String) -> Unit
) {
var textState by rememberSaveable { mutableStateOf("") }
Expand All @@ -83,6 +85,8 @@ fun EinsenInputTextField(
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp),
value = value,
readOnly = readOnly,
enabled = enabled,
onValueChange = {
textState = it
when (textState.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ interface TaskDao {
@Query("SELECT * FROM task where id=:id")
fun findByID(id: Int): Flow<Task>

@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)

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/dev/spikeysanju/einsen/di/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
}
4 changes: 3 additions & 1 deletion app/src/main/java/dev/spikeysanju/einsen/model/task/Task.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
44 changes: 44 additions & 0 deletions app/src/main/java/dev/spikeysanju/einsen/utils/DateTimeHelper.kt
Original file line number Diff line number Diff line change
@@ -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.utils

import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*

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
}
67 changes: 67 additions & 0 deletions app/src/main/java/dev/spikeysanju/einsen/utils/DateValidator.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
*
* * 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<DateValidator> {
override fun createFromParcel(parcel: Parcel): DateValidator {
return DateValidator(parcel)
}

override fun newArray(size: Int): Array<DateValidator?> {
return arrayOfNulls(size)
}
}
}
Loading

0 comments on commit d232dce

Please sign in to comment.