diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index 6538bfe..bee7c8d 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -24,9 +24,16 @@ jobs:
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew build
- - name: Build Debug APK
+ # Create APK Debug
+ - name: Build apk debug project (APK)
run: ./gradlew assembleDebug
- - name: Create APK directory
- run: mkdir -p apk
- - name: Copy APK to directory
- run: cp app/build/outputs/apk/debug/*.apk apk/
+ # Create an artifacts folder if it doesn't exist, and move APK into it
+ - name: Move APK to artifacts folder
+ run: |
+ mkdir -p ${{ github.workspace }}/artifacts/
+ mv ${{ env.main_project_module }}/build/outputs/apk/debug/* ${{ github.workspace }}/artifacts/
+ - name: Upload APK Debug - ${{ env.repository_name }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: Tasky_debug
+ path: ${{ github.workspace }}/artifacts/
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
index 5a2d133..0c0c338 100644
--- a/.idea/deploymentTargetDropDown.xml
+++ b/.idea/deploymentTargetDropDown.xml
@@ -1,17 +1,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ae388c2..0897082 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -4,16 +4,15 @@
diff --git a/app/build.gradle b/app/build.gradle
index f2b11eb..f9c3735 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -12,8 +12,8 @@ android {
applicationId "com.thatsmanmeet.taskyapp"
minSdk 26
targetSdk 34
- versionCode 25
- versionName "2.4.1"
+ versionCode 26
+ versionName "2.4.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
@@ -71,7 +71,7 @@ dependencies {
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
- def room_version = "2.6.0"
+ def room_version = "2.6.1"
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
implementation "androidx.compose.runtime:runtime-livedata:1.5.4"
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/components/ActionDialogBox.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/components/ActionDialogBox.kt
index a588d7e..86bebf3 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/components/ActionDialogBox.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/components/ActionDialogBox.kt
@@ -26,7 +26,6 @@ fun ActionDialogBox(
if(isDialogShowing.value){
AlertDialog(
onDismissRequest = {
- onDismissClick()
isDialogShowing.value = false
},
confirmButton = {
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/components/AddTodoDialog.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/components/AddTodoDialog.kt
index 271c85c..3c16d29 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/components/AddTodoDialog.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/components/AddTodoDialog.kt
@@ -163,7 +163,7 @@ fun addTodoDialog(
},
confirmButton = {
Button(onClick = {
- if (enteredText1.isNotEmpty() && descriptionText.isNotEmpty()){
+ if (enteredText1.isNotEmpty()){
val todo = Todo(
ID = null,
title = enteredText1,
@@ -216,7 +216,7 @@ fun addTodoDialog(
isRepeating = false
}
else{
- Toast.makeText(context,"Fill in all fields",Toast.LENGTH_SHORT).show()
+ Toast.makeText(context,"Task name is required.",Toast.LENGTH_SHORT).show()
}
}
) {
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/components/DeletedTodoItem.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/components/DeletedTodoItem.kt
new file mode 100644
index 0000000..eae1862
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/components/DeletedTodoItem.kt
@@ -0,0 +1,103 @@
+package com.thatsmanmeet.taskyapp.components
+
+import android.content.Context
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.thatsmanmeet.taskyapp.room.Todo
+import com.thatsmanmeet.taskyapp.room.TodoViewModel
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodo
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodoViewModel
+import com.thatsmanmeet.taskyapp.screens.currentDateTimeComparator
+import com.thatsmanmeet.taskyapp.screens.scheduleNotification
+
+
+@Composable
+fun DeletedTodoItem(
+ deletedTodo: DeletedTodo,
+ todoViewModel: TodoViewModel,
+ deletedTodoViewModel: DeletedTodoViewModel,
+ context:Context = LocalContext.current,
+ modifier: Modifier = Modifier
+) {
+ val isShowing = remember {
+ mutableStateOf(false)
+ }
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .padding(10.dp)
+ .heightIn(60.dp)
+ .clip(RoundedCornerShape(10.dp))
+ .clickable {
+ isShowing.value = true
+ }
+ .background(MaterialTheme.colorScheme.inverseOnSurface),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Box(modifier = modifier
+ .fillMaxWidth()
+ .padding(10.dp)){
+ Text(
+ text = deletedTodo.title!!,
+ fontSize = 20.sp,
+ textDecoration = if(deletedTodo.isCompleted) TextDecoration.LineThrough else TextDecoration.None
+ )
+ }
+ }
+ if(isShowing.value){
+ ActionDialogBox(
+ isDialogShowing = isShowing,
+ title = "Choose Action",
+ message = "Do you want to restore or delete this task?",
+ confirmButtonText = "Restore" ,
+ dismissButtonText = "Delete",
+ onConfirmClick = {
+ val newTodo = Todo(
+ ID = deletedTodo.ID,
+ title = deletedTodo.title,
+ todoDescription = deletedTodo.todoDescription,
+ isCompleted = deletedTodo.isCompleted,
+ date = deletedTodo.date,
+ time = deletedTodo.time,
+ notificationID = deletedTodo.notificationID,
+ isRecurring = deletedTodo.isRecurring
+ )
+ todoViewModel.insertTodo(newTodo)
+ if(newTodo.time!!.isNotEmpty()){
+ currentDateTimeComparator(inputDate = newTodo.date!!, inputTime = newTodo.time!!) {
+ scheduleNotification(
+ context = context,
+ titleText = newTodo.title!!,
+ messageText = newTodo.todoDescription!!,
+ time = "${newTodo.date} ${newTodo.time}",
+ todo = newTodo
+ )
+ }
+ }
+ deletedTodoViewModel.deleteDeletedTodo(deletedTodo)
+ },
+ onDismissClick = {
+ deletedTodoViewModel.deleteDeletedTodo(deletedTodo)
+ },
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/components/TaskList.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/components/TaskList.kt
index 03b8611..3f0d1b3 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/components/TaskList.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/components/TaskList.kt
@@ -26,6 +26,7 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.SwipeToDismiss
import androidx.compose.material3.rememberDismissState
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.mutableStateOf
@@ -40,6 +41,8 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import com.thatsmanmeet.taskyapp.room.Todo
import com.thatsmanmeet.taskyapp.room.TodoViewModel
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodo
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodoViewModel
import com.thatsmanmeet.taskyapp.screens.CurrentDateTimeComparator
import com.thatsmanmeet.taskyapp.screens.cancelNotification
import com.thatsmanmeet.taskyapp.screens.scheduleNotification
@@ -56,6 +59,7 @@ fun TaskList(
state: LazyListState,
list : List,
todoViewModel: TodoViewModel,
+ deletedTodoViewModel: DeletedTodoViewModel,
onClick : (Int) -> Unit,
searchText: String,
coroutineScope: CoroutineScope,
@@ -96,39 +100,37 @@ fun TaskList(
if(dismissState.isDismissed(direction = DismissDirection.EndToStart)){
isSwipeDeleteDialogShowing.value = true
- ActionDialogBox(
- isDialogShowing = isSwipeDeleteDialogShowing,
- title = "Delete Task?",
- message = "Do you want to delete this task?",
- confirmButtonText = "Delete",
- dismissButtonText = "Cancel",
- onConfirmClick = {
- todoViewModel.deleteTodo(currentItem)
- },
- onDismissClick = {
- isSwipeDeleteDialogShowing.value = false
- coroutineScope.launch {
- dismissState.reset()
- }
- },
- confirmButtonColor = Color(0xFFF75F5F),
- confirmButtonContentColor = Color.White
- )
-// LaunchedEffect(Unit){
-// val result = snackbarHostState.showSnackbar(
-// message = "Task will be deleted soon!",
-// actionLabel = "Undo",
-// duration = SnackbarDuration.Short
-// )
-// when(result){
-// SnackbarResult.Dismissed -> {
-// todoViewModel.deleteTodo(currentItem)
-// }
-// SnackbarResult.ActionPerformed -> {
+ deletedTodoViewModel.insertDeletedTodo(DeletedTodo(
+ ID = currentItem.ID,
+ title = currentItem.title,
+ todoDescription = currentItem.todoDescription,
+ isCompleted = currentItem.isCompleted,
+ date = currentItem.date,
+ time = currentItem.time,
+ isRecurring = currentItem.isRecurring,
+ notificationID = currentItem.notificationID,
+ todoDeletionDate = getDate30DaysLater(currentItem.date!!)
+ ))
+ todoViewModel.deleteTodo(currentItem)
+ cancelNotification(context,currentItem)
+// ActionDialogBox(
+// isDialogShowing = isSwipeDeleteDialogShowing,
+// title = "Delete Task?",
+// message = "Do you want to delete this task?",
+// confirmButtonText = "Delete",
+// dismissButtonText = "Cancel",
+// onConfirmClick = {
+// todoViewModel.deleteTodo(currentItem)
+// },
+// onDismissClick = {
+// isSwipeDeleteDialogShowing.value = false
+// coroutineScope.launch {
// dismissState.reset()
// }
-// }
-// }
+// },
+// confirmButtonColor = Color(0xFFF75F5F),
+// confirmButtonContentColor = Color.White
+// )
}
if(dismissState.isDismissed(direction = DismissDirection.StartToEnd)){
@@ -214,4 +216,13 @@ fun TaskList(
}
}
}
+}
+
+fun getDate30DaysLater(enteredDate:String):String{
+ val sdf = SimpleDateFormat("dd/MM/yyyy",Locale.getDefault())
+ val date = sdf.parse(enteredDate)
+ val calendar = Calendar.getInstance()
+ calendar.time = date!!
+ calendar.add(Calendar.DAY_OF_MONTH,30)
+ return sdf.format(calendar.time)
}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/receiver/RepeatingTasksReceiver.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/receiver/RepeatingTasksReceiver.kt
index 5627e8d..f5f7393 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/receiver/RepeatingTasksReceiver.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/receiver/RepeatingTasksReceiver.kt
@@ -10,6 +10,7 @@ import androidx.room.Room
import com.thatsmanmeet.taskyapp.constants.Constants
import com.thatsmanmeet.taskyapp.room.Todo
import com.thatsmanmeet.taskyapp.room.TodoDatabase
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodoDatabase
import com.thatsmanmeet.taskyapp.screens.scheduleNotification
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -28,6 +29,11 @@ class RepeatingTasksReceiver : BroadcastReceiver() {
TodoDatabase::class.java,
"todo_database"
).build()
+ val deletedTodoDatabase = Room.databaseBuilder(
+ context!!.applicationContext,
+ DeletedTodoDatabase::class.java,
+ "deleted_todo_database"
+ ).build()
coroutineScope.launch {
withTimeout(10000) {
todoDatabase.todoDao().getAllTodosFlow().collect{todos->
@@ -60,6 +66,21 @@ class RepeatingTasksReceiver : BroadcastReceiver() {
}
}
}
+ coroutineScope.launch {
+ withTimeout(10000){
+ deletedTodoDatabase.deletedTodoDao().getAllTodosFlow().collect{deletedTodos->
+ val currentDate =
+ SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(
+ Date()
+ )
+ for(todo in deletedTodos){
+ if(currentDate == todo.todoDeletionDate){
+ deletedTodoDatabase.deletedTodoDao().deleteTodo(todo)
+ }
+ }
+ }
+ }
+ }
val nextAlarmIntent = Intent(context.applicationContext,RepeatingTasksReceiver::class.java).also {
it.action = "repeating_tasks"
}
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/TodoRepository.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/TodoRepository.kt
index ab30b89..287accc 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/room/TodoRepository.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/TodoRepository.kt
@@ -18,5 +18,4 @@ class TodoRepository(private val todoDao: TodoDao) {
}
fun getAllTodosFlow() : Flow> = todoDao.getAllTodosFlow()
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodo.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodo.kt
new file mode 100644
index 0000000..9ea0471
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodo.kt
@@ -0,0 +1,19 @@
+package com.thatsmanmeet.taskyapp.room.deletedtodo
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity(tableName = "deleted_todo_table")
+data class DeletedTodo(
+ @PrimaryKey(autoGenerate = true) var ID:Long? = null,
+ @ColumnInfo(name = "title") var title:String? = "",
+ @ColumnInfo(name = "completed") var isCompleted:Boolean = false,
+ @ColumnInfo(name = "date") var date:String? = "",
+ @ColumnInfo(name = "time") var time:String? = "",
+ @ColumnInfo(name = "notificationID", defaultValue = "0") var notificationID:Int = 0,
+ @ColumnInfo(name = "is_Recurring", defaultValue = "false") var isRecurring : Boolean = false,
+ @ColumnInfo(name = "description", defaultValue = "") var todoDescription : String? = "",
+ @ColumnInfo(name = "deletionDate", defaultValue = "") var todoDeletionDate: String ? = ""
+)
+
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDao.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDao.kt
new file mode 100644
index 0000000..2dbae53
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDao.kt
@@ -0,0 +1,30 @@
+package com.thatsmanmeet.taskyapp.room.deletedtodo
+
+import androidx.lifecycle.LiveData
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import kotlinx.coroutines.flow.Flow
+
+@Dao
+interface DeletedTodoDao {
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun addTodo(todo: DeletedTodo)
+
+ @Update(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun updateTodo(todo: DeletedTodo)
+
+ @Delete
+ suspend fun deleteTodo(todo: DeletedTodo)
+
+ @Query("SELECT * FROM deleted_todo_table ORDER BY ID ASC")
+ fun getAllTodos() : LiveData>
+
+ @Query("SELECT * FROM deleted_todo_table ORDER BY ID ASC")
+ fun getAllTodosFlow() : Flow>
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDatabase.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDatabase.kt
new file mode 100644
index 0000000..110f076
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoDatabase.kt
@@ -0,0 +1,35 @@
+package com.thatsmanmeet.taskyapp.room.deletedtodo
+
+import android.content.Context
+import androidx.room.Database
+import androidx.room.Room
+import androidx.room.RoomDatabase
+
+@Database(
+ entities = [DeletedTodo::class],
+ version = 1
+)
+abstract class DeletedTodoDatabase : RoomDatabase() {
+
+ abstract fun deletedTodoDao(): DeletedTodoDao
+
+ companion object{
+ @Volatile
+ private var INSTANCE : DeletedTodoDatabase? = null
+
+ fun getInstance(context: Context): DeletedTodoDatabase{
+ synchronized(this){
+ var instance = INSTANCE
+ if(instance == null){
+ instance = Room.databaseBuilder(
+ context.applicationContext,
+ DeletedTodoDatabase::class.java,
+ "deleted_todo_database"
+ ).allowMainThreadQueries().build()
+ INSTANCE = instance
+ }
+ return instance
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoRepository.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoRepository.kt
new file mode 100644
index 0000000..70905f3
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoRepository.kt
@@ -0,0 +1,20 @@
+package com.thatsmanmeet.taskyapp.room.deletedtodo
+
+
+import kotlinx.coroutines.flow.Flow
+
+class DeletedTodoRepository(private val deletedTodoDao: DeletedTodoDao) {
+ suspend fun insertTodo(todo: DeletedTodo){
+ deletedTodoDao.addTodo(todo)
+ }
+
+ suspend fun updateTodo(todo: DeletedTodo){
+ deletedTodoDao.updateTodo(todo)
+ }
+
+ suspend fun deleteTodo(todo: DeletedTodo){
+ deletedTodoDao.deleteTodo(todo)
+ }
+
+ fun getAllTodosFlow() : Flow> = deletedTodoDao.getAllTodosFlow()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoViewModel.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoViewModel.kt
new file mode 100644
index 0000000..5898d3e
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/room/deletedtodo/DeletedTodoViewModel.kt
@@ -0,0 +1,31 @@
+package com.thatsmanmeet.taskyapp.room.deletedtodo
+
+import android.app.Application
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.launch
+
+class DeletedTodoViewModel(application: Application) : ViewModel() {
+
+ private var repository:DeletedTodoRepository
+ val getAllDeletedTodos: Flow>
+
+ init {
+ val dao = DeletedTodoDatabase.getInstance(application).deletedTodoDao()
+ repository = DeletedTodoRepository(dao)
+ getAllDeletedTodos = repository.getAllTodosFlow()
+ }
+
+ fun insertDeletedTodo(deletedTodo: DeletedTodo){
+ viewModelScope.launch {
+ repository.insertTodo(deletedTodo)
+ }
+ }
+ fun deleteDeletedTodo(deletedTodo: DeletedTodo){
+ viewModelScope.launch {
+ repository.deleteTodo(deletedTodo)
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/App.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/App.kt
index aff9679..1df4a1d 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/App.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/App.kt
@@ -19,9 +19,12 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavHostController
+import androidx.navigation.compose.rememberNavController
+import com.thatsmanmeet.taskyapp.BuildConfig
import com.thatsmanmeet.taskyapp.R
import com.thatsmanmeet.taskyapp.components.OpenEditTodoDialog
import com.thatsmanmeet.taskyapp.components.SearchBarTop
@@ -35,9 +38,11 @@ import com.thatsmanmeet.taskyapp.notification.channelID
import com.thatsmanmeet.taskyapp.receiver.RepeatingTasksReceiver
import com.thatsmanmeet.taskyapp.room.Todo
import com.thatsmanmeet.taskyapp.room.TodoViewModel
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodoViewModel
import com.thatsmanmeet.taskyapp.ui.theme.TaskyTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.text.SimpleDateFormat
import java.util.*
@@ -51,6 +56,7 @@ fun MyApp(
val activity = LocalContext.current as Activity
val context = LocalContext.current
val todoViewModel = TodoViewModel(activity.application)
+ val deletedTodoViewModel = DeletedTodoViewModel(activity.application)
val listState = rememberLazyListState()
val selectedItem = rememberSaveable {
mutableIntStateOf(-1)
@@ -96,6 +102,10 @@ fun MyApp(
SnackbarHostState()
}
+ val coroutineScope = rememberCoroutineScope()
+
+ val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
+
createNotificationChannel(context.applicationContext)
// setup settings store
val settingsStore = SettingsStore(context)
@@ -108,138 +118,198 @@ fun MyApp(
else -> {true}
}
) {
- Scaffold(
- snackbarHost = {SnackbarHost(hostState = snackBarHostState)},
- topBar = {
- TopAppBar(
- title = {
- Row(
- modifier = modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Text(
- text = stringResource(id = R.string.app_name),
- fontSize = 25.sp
- )
- SearchBarTop(searchText) { searchText = it }
- Spacer(modifier = modifier.width(0.dp))
+ ModalNavigationDrawer(
+ drawerState = drawerState,
+ gesturesEnabled = true,
+ drawerContent = {
+ ModalDrawerSheet {
+ Row(
+ modifier = modifier.fillMaxWidth().padding(16.dp),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text("Tasky")
+ Text(text = "V${BuildConfig.VERSION_NAME}")
+ }
+ HorizontalDivider()
+ NavigationDrawerItem(
+ modifier = modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp),
+ icon = { Icon(imageVector = Icons.Default.Delete, contentDescription = null)},
+ label = { Text(text = "Deleted Tasks") },
+ selected = false,
+ onClick = {
+ coroutineScope.launch {
+ drawerState.close()
+ }
+ navHostController.navigate(route = Screen.DeletedTodosScreen.route)
+ }
+ )
+ NavigationDrawerItem(
+ modifier = modifier.padding(start = 16.dp, end = 16.dp),
+ icon = { Icon(imageVector = Icons.Default.Info, contentDescription = null)},
+ label = { Text(text = "Guide") },
+ selected = false,
+ onClick = {
+ coroutineScope.launch {
+ drawerState.close()
+ }
+ navHostController.navigate(route = Screen.GuideScreen.route)
+ }
+ )
+ NavigationDrawerItem(
+ modifier = modifier.padding(bottom = 16.dp,start = 16.dp, end = 16.dp),
+ icon = { Icon(imageVector = Icons.Default.Settings, contentDescription = null)},
+ label = { Text(text = "Settings") },
+ selected = false,
+ onClick = {
+ coroutineScope.launch {
+ drawerState.close()
+ }
+ navHostController.navigate(route = Screen.SettingsScreen.route)
+ }
+ )
+ }
+ }
+ ) {
+ Scaffold(
+ snackbarHost = {SnackbarHost(hostState = snackBarHostState)},
+ topBar = {
+ TopAppBar(
+ navigationIcon = {
IconButton(onClick = {
- // Implement Navigation to settings
- navHostController.navigate(route = Screen.SettingsScreen.route)
- }) {
- Icon(
- imageVector = Icons.Default.Settings,
- contentDescription = null
+ coroutineScope.launch {
+ drawerState.apply {
+ if(isClosed) open() else close()
+ }
+ }
+ }) {
+ Icon(
+ imageVector = Icons.Default.Menu,
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.onPrimary
+ )
+ }
+ },
+ title = {
+ Row(
+ modifier = modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
+ Text(
+ text = stringResource(id = R.string.app_name),
+ fontSize = 25.sp
)
+ SearchBarTop(searchText) { searchText = it }
}
- }
- },
- colors = topAppBarColors.topAppBarColors(
- containerColor = MaterialTheme.colorScheme.primary,
- titleContentColor = MaterialTheme.colorScheme.onPrimary
+ },
+ colors = topAppBarColors.topAppBarColors(
+ containerColor = MaterialTheme.colorScheme.primary,
+ titleContentColor = MaterialTheme.colorScheme.onPrimary
+ )
)
+ },
+ floatingActionButton = {
+ ExtendedFloatingActionButton(
+ text = { Text(text = stringResource(R.string.add_task_button)) },
+ icon = { Icon(painter = painterResource(id = R.drawable.ic_add_task), contentDescription = null) },
+ onClick = {
+ openDialog.value = true
+ },
+ expanded = listState.isScrollingUp()
+ )
+ }
+ ) { paddingValues ->
+ enteredText = addTodoDialog(
+ openDialog,
+ enteredText,
+ descriptionText,
+ dateText,
+ isDateDialogShowing,
+ context,
+ timeText,
+ isTimeDialogShowing,
+ todoViewModel,
+ isRepeatingState.value
)
- },
- floatingActionButton = {
- ExtendedFloatingActionButton(
- text = { Text(text = stringResource(R.string.add_task_button)) },
- icon = { Icon(painter = painterResource(id = R.drawable.ic_add_task), contentDescription = null) },
- onClick = {
- openDialog.value = true
- },
- expanded = listState.isScrollingUp()
- )
- }
- ) { paddingValues ->
- enteredText = addTodoDialog(
- openDialog,
- enteredText,
- descriptionText,
- dateText,
- isDateDialogShowing,
- context,
- timeText,
- isTimeDialogShowing,
- todoViewModel,
- isRepeatingState.value
- )
- Surface(
- modifier = modifier
- .fillMaxSize()
- .padding(paddingValues),
- color = MaterialTheme.colorScheme.background
- ) {
- if(todoListFromFlow.isEmpty()){
- Box(modifier = modifier
+ Surface(
+ modifier = modifier
.fillMaxSize()
.padding(paddingValues),
- contentAlignment = Alignment.Center) {
- Column(
- modifier = modifier,
- horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = Arrangement.Center
- ) {
- Icon(
- modifier = modifier
- .size(50.dp)
- .alpha(0.8f),
- imageVector = Icons.Filled.Check,
- contentDescription = null,
- tint = MaterialTheme.colorScheme.primary
- )
- Text(
- text = stringResource(R.string.empty_list_no_tasks_text),
- fontSize = 30.sp,
- color = MaterialTheme.colorScheme.primary,
- fontWeight = FontWeight.Light
- )
+ color = MaterialTheme.colorScheme.background
+ ) {
+ if(todoListFromFlow.isEmpty()){
+ Box(modifier = modifier
+ .fillMaxSize()
+ .padding(paddingValues),
+ contentAlignment = Alignment.Center) {
+ Column(
+ modifier = modifier,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Icon(
+ modifier = modifier
+ .size(50.dp)
+ .alpha(0.8f),
+ imageVector = Icons.Filled.Check,
+ contentDescription = null,
+ tint = MaterialTheme.colorScheme.primary
+ )
+ Text(
+ text = stringResource(R.string.empty_list_no_tasks_text),
+ fontSize = 30.sp,
+ color = MaterialTheme.colorScheme.primary,
+ fontWeight = FontWeight.Light
+ )
+ }
}
+ }else {
+ TaskList(
+ state = listState,
+ list = todoListFromFlow,
+ todoViewModel = todoViewModel,
+ deletedTodoViewModel = deletedTodoViewModel,
+ onClick = {index->
+ selectedItem.intValue = index
+ openEditDialog.value = true
+ },
+ searchText = searchText,
+ coroutineScope = rememberCoroutineScope(),
+ snackbarHostState = snackBarHostState
+ )
+ }
+ if (openEditDialog.value){
+ OpenEditTodoDialog(
+ todoListFromFlow,
+ selectedItem,
+ openEditDialog,
+ todoViewModel,
+ enteredText,
+ todoListFromFlow[selectedItem.intValue].todoDescription!!,
+ context
+ )
}
- }else {
- TaskList(
- state = listState,
- list = todoListFromFlow,
- todoViewModel = todoViewModel,
- onClick = {index->
- selectedItem.intValue = index
- openEditDialog.value = true
- },
- searchText = searchText,
- coroutineScope = rememberCoroutineScope(),
- snackbarHostState = snackBarHostState
- )
- }
- if (openEditDialog.value){
- OpenEditTodoDialog(
- todoListFromFlow,
- selectedItem,
- openEditDialog,
- todoViewModel,
- enteredText,
- todoListFromFlow[selectedItem.intValue].todoDescription!!,
- context
- )
}
+
}
+ if(todoViewModel.isAnimationPlayingState.value && (savedAnimationKey.value == true || savedAnimationKey.value == null)){
+ Column(modifier = modifier.fillMaxSize()) {
+ TaskCompleteAnimations(
+ isLottiePlaying = isLottiePlaying,
+ modifier = modifier.fillMaxSize()
+ )
+ LaunchedEffect(Unit){
+ delay(2200)
+ withContext(Dispatchers.Main){
+ todoViewModel.isAnimationPlayingState.value = false
+ }
- }
- if(todoViewModel.isAnimationPlayingState.value && (savedAnimationKey.value == true || savedAnimationKey.value == null)){
- Column(modifier = modifier.fillMaxSize()) {
- TaskCompleteAnimations(
- isLottiePlaying = isLottiePlaying,
- modifier = modifier.fillMaxSize()
- )
- LaunchedEffect(Unit){
- delay(2200)
- withContext(Dispatchers.Main){
- todoViewModel.isAnimationPlayingState.value = false
}
-
}
}
}
- }
+ }
}
@@ -251,8 +321,6 @@ fun createNotificationChannel(context: Context){
channel.description = desc
channel.enableLights(true)
channel.enableVibration(true)
-// val attributes = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION_EVENT).build()
-// channel.setSound(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.packageName + "/raw/notifications"),attributes)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if(notificationManager.getNotificationChannel("Reminder Channel") != null){
notificationManager.deleteNotificationChannel("Reminder Channel")
@@ -371,3 +439,36 @@ fun CurrentDateTimeComparator(
onTruePerform()
}
}
+
+
+fun currentDateTimeComparator(
+ inputDate:String,
+ inputTime:String,
+ onTruePerform: () -> Unit
+) {
+ val calendarInstance = Calendar.getInstance()
+ val currentDate = calendarInstance.apply {
+ set(Calendar.HOUR_OF_DAY, 0)
+ set(Calendar.MINUTE, 0)
+ set(Calendar.SECOND, 0)
+ }
+ val format = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
+ val parsedDate = format.parse(inputDate)
+ val calendar = calendarInstance.apply {
+ time = parsedDate!!
+ set(Calendar.HOUR_OF_DAY, inputTime.substringBefore(":").toInt())
+ set(Calendar.MINUTE, inputTime.substringAfter(":").toInt())
+ set(Calendar.SECOND, 0)
+ }
+ val currentTime = Calendar.getInstance().timeInMillis
+ if(calendar >= currentDate && calendar.timeInMillis >= currentTime){
+ onTruePerform()
+ }
+}
+
+
+@Preview
+@Composable
+fun DisplayAppScreen() {
+ MyApp(navHostController = rememberNavController())
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/DeletedTodoScreen.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/DeletedTodoScreen.kt
new file mode 100644
index 0000000..c8c7753
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/DeletedTodoScreen.kt
@@ -0,0 +1,118 @@
+package com.thatsmanmeet.taskyapp.screens
+
+import android.app.Activity
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults.topAppBarColors
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.rememberNavController
+import com.thatsmanmeet.taskyapp.components.DeletedTodoItem
+import com.thatsmanmeet.taskyapp.datastore.SettingsStore
+import com.thatsmanmeet.taskyapp.room.TodoViewModel
+import com.thatsmanmeet.taskyapp.room.deletedtodo.DeletedTodoViewModel
+import com.thatsmanmeet.taskyapp.ui.theme.TaskyTheme
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun DeletedTodoScreen(
+ navHostController: NavHostController,
+ modifier: Modifier = Modifier
+) {
+ val context = LocalContext.current
+ val activity = context as Activity
+ val settingStore = SettingsStore(context)
+ val savedThemeKey = settingStore.getThemeModeKey.collectAsState(initial = "")
+ val deletedTodoViewModel = DeletedTodoViewModel(activity.application)
+ val todoViewModel = TodoViewModel(activity.application)
+ val deletedTodoList = deletedTodoViewModel.getAllDeletedTodos.collectAsState(initial = emptyList())
+
+ TaskyTheme(darkTheme = when (savedThemeKey.value) {
+ "0" -> {
+ isSystemInDarkTheme()
+ }
+ "1" -> {false}
+ else -> {true}
+ }) {
+ Scaffold(
+ modifier = modifier.fillMaxSize(),
+ topBar = {
+ TopAppBar(
+ title = {
+ Text(text = "Deleted Tasks")
+ }, navigationIcon = {
+ IconButton(onClick = {
+ navHostController.navigate(route = Screen.MyApp.route){
+ popUpTo(route = Screen.MyApp.route){
+ inclusive = true
+ }
+ }
+ }) {
+ Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Arrow back", tint = MaterialTheme.colorScheme.onPrimary)
+ }
+ },
+ colors = topAppBarColors(
+ containerColor = MaterialTheme.colorScheme.primary,
+ titleContentColor = MaterialTheme.colorScheme.onPrimary
+ )
+ )
+ }
+ ) {paddingValues ->
+ Column(
+ modifier = modifier.padding(paddingValues),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Box(
+ modifier = modifier
+ .fillMaxWidth()
+ .height(100.dp)
+ .padding(16.dp)
+ ){
+ Text(text = "Deleted Tasks will be automatically deleted in 30 days. Tap on a task to restore or permanently delete it.", fontSize = 15.sp)
+ }
+ LazyColumn{
+ items(deletedTodoList.value){deletedTodo->
+ DeletedTodoItem(
+ deletedTodo = deletedTodo,
+ todoViewModel = todoViewModel,
+ deletedTodoViewModel = deletedTodoViewModel
+ )
+ Spacer(modifier = modifier.height(5.dp))
+ }
+
+ }
+ }
+ }
+ }
+
+}
+
+@Preview
+@Composable
+fun PreviewDeletedTodoScreen() {
+ DeletedTodoScreen(rememberNavController())
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/GuideScreen.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/GuideScreen.kt
new file mode 100644
index 0000000..85ba1d1
--- /dev/null
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/GuideScreen.kt
@@ -0,0 +1,161 @@
+package com.thatsmanmeet.taskyapp.screens
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.material3.TopAppBar
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.navigation.NavHostController
+import com.thatsmanmeet.taskyapp.datastore.SettingsStore
+import com.thatsmanmeet.taskyapp.ui.theme.TaskyTheme
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun GuideScreen(
+ navHostController: NavHostController,
+ modifier: Modifier = Modifier
+) {
+ val context = LocalContext.current
+ val settingStore = SettingsStore(context)
+ val savedThemeKey = settingStore.getThemeModeKey.collectAsState(initial = "")
+ val height = 12.dp
+ TaskyTheme(
+ darkTheme = when (savedThemeKey.value) {
+ "0" -> {
+ isSystemInDarkTheme()
+ }
+ "1" -> {false}
+ else -> {true}
+ }
+ ) {
+ Scaffold(
+ topBar = {
+ TopAppBar(
+ title = { Text(text = "Guide") },
+ navigationIcon = {
+ IconButton(onClick = {
+ navHostController.navigate(route = Screen.MyApp.route){
+ popUpTo(route = Screen.MyApp.route){
+ inclusive = true
+ }
+ }
+ }) {
+ Icon(imageVector = Icons.Default.ArrowBack, contentDescription = null)
+ }
+ },
+ colors = TopAppBarDefaults.topAppBarColors(
+ containerColor = MaterialTheme.colorScheme.primary,
+ titleContentColor = MaterialTheme.colorScheme.onPrimary,
+ navigationIconContentColor = MaterialTheme.colorScheme.onPrimary
+ )
+ )
+ }
+ ) {paddingValues ->
+ Column(
+ modifier = modifier
+ .verticalScroll(rememberScrollState())
+ .fillMaxSize()
+ .padding(paddingValues)
+ .padding(16.dp)
+ ) {
+ Text(
+ text = "Welcome to Tasky, a free and open source, minimal and aesthetic task management app. This guide will provide you with everything you can do in this app.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "1. On very first start, you will be greeted with a permission screen (if your android version is 13 or above). Here the app will ask for notification permission that is required to provide you with notifications on time.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "2. You will be on the task screen. Here the navigation bar have 3 things (menu icon, app name and search icon). On the screen you have a add tasks button and an empty list.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "3. You can click on add task and an dialog will open where you have to enter task name (description is optional). You can set date and time of the task and can set if the notification should be repeated daily or not just like a routine habit tracker. You can save task by clicking Add button. Notification will display on set date (everyday if repeating option is checked)/time and notification will contain tasks title and description.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "4. You will see the task added on the screen. You can tap on the task and an edit dialog will open where you can edit or delete the task.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "5. You can also swipe an individual task. Swiping left to right on task will mark task as complete/uncompleted and swiping from right to left will delete the task and will add it to trash.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "6. On top you can see a search icon. You can click on it and search for a task. This will search both task and description of all the tasks.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "7. On top you can see a search icon. You can click on it and search for a task. This will search both task and description of all the tasks.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "8. On Clicking Menu button a navigation drawer will open and contains app name and version code. It contains three items (Deleted Tasks, Guide and Settings).",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "9. On Deleted Tasks Screen you can see all the tasks you deleted. You can only tap on the item to either delete them permanently or restore them. You cannot edit them. Also if they are completed they have line-through the text. ",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "10. Guide button will bring you to this guide. ",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "11. Settings button will take you to settings screen where you can tweak various settings. ",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ Spacer(modifier = modifier.height(height))
+ Text(
+ text = "12. In Settings screen, you can set app theme, can enable/disable confetti animations on task complete, can enable/disable task completion sounds, switch to 12/24 hour clock, backup/restore tasks locally and enable autostart.",
+ fontSize = 16.sp,
+ textAlign = TextAlign.Justify
+ )
+ }
+ }
+ }
+ }
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/NavGraph.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/NavGraph.kt
index 19fdddc..24fad38 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/NavGraph.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/NavGraph.kt
@@ -49,5 +49,13 @@ fun SetupNavGraph(
){
MyApp(navHostController = navController)
}
+
+ composable(route = Screen.DeletedTodosScreen.route){
+ DeletedTodoScreen(navHostController = navController)
+ }
+
+ composable(route = Screen.GuideScreen.route){
+ GuideScreen(navHostController = navController)
+ }
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/Screen.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/Screen.kt
index b887282..cd2357a 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/Screen.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/Screen.kt
@@ -5,4 +5,7 @@ sealed class Screen(val route:String){
object PermissionScreen: Screen("permission_screen")
object SettingsScreen : Screen("settings_screen")
object SearchScreen: Screen("search_screen")
+ object DeletedTodosScreen:Screen("deleted_todo_screen")
+
+ object GuideScreen:Screen("guide_screen")
}
diff --git a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/SettingsScreen.kt b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/SettingsScreen.kt
index bdf5efb..6bafcb8 100644
--- a/app/src/main/java/com/thatsmanmeet/taskyapp/screens/SettingsScreen.kt
+++ b/app/src/main/java/com/thatsmanmeet/taskyapp/screens/SettingsScreen.kt
@@ -23,6 +23,7 @@ import androidx.core.net.toUri
import androidx.navigation.NavHostController
import com.thatsmanmeet.taskyapp.MainActivity
import com.thatsmanmeet.taskyapp.R
+import com.thatsmanmeet.taskyapp.components.ActionDialogBox
import com.thatsmanmeet.taskyapp.components.SettingsComponent
import com.thatsmanmeet.taskyapp.components.ThemeChangerDialog
import com.thatsmanmeet.taskyapp.datastore.SettingsStore
@@ -46,9 +47,6 @@ fun SettingsScreen(
val scope = rememberCoroutineScope()
val settingStore = SettingsStore(context)
val savedThemeKey = settingStore.getThemeModeKey.collectAsState(initial = "")
- val isCheckedState = remember {
- mutableStateOf(isChecked.value)
- }
val shouldShowAnimationState = remember {
mutableStateOf(shouldShowAnimation.value)
}
@@ -58,7 +56,7 @@ fun SettingsScreen(
val is24HourClockState = remember {
mutableStateOf(is24HourClockKey.value)
}
- var isDialogShowingState by rememberSaveable {
+ val isBackupDialogShowingState = rememberSaveable {
mutableStateOf(false)
}
val isThemeChangerShowing = rememberSaveable {
@@ -245,7 +243,7 @@ fun SettingsScreen(
settingText = stringResource(id = R.string.settings_backup_restore_information_text),
painterResourceID = R.drawable.ic_history
) {
- isDialogShowingState = true
+ isBackupDialogShowingState.value = true
}
// Visit Github Card
SettingsComponent(
@@ -257,34 +255,19 @@ fun SettingsScreen(
}
}
}
- if(isDialogShowingState){
- AlertDialog(
- onDismissRequest = {
- isDialogShowingState = false
- },
- title = {
- Text(text = stringResource(R.string.settings_backup_restore))
- },
- text = {
- Text(text = stringResource(R.string.settings_backup_restore_information_text))
- },
- confirmButton = {
- OutlinedButton(onClick = {
+ if(isBackupDialogShowingState.value){
+ ActionDialogBox(
+ isDialogShowing = isBackupDialogShowingState,
+ title = stringResource(id = R.string.settings_backup_restore) ,
+ message = stringResource(id = R.string.settings_backup_restore_information_text) ,
+ confirmButtonText = "Restore",
+ dismissButtonText = "Backup",
+ onConfirmClick = {
MainActivity().restoreFile(context = activity,dbPath.toUri())
- isDialogShowingState = false
- }) {
- Text(text = "Restore")
- }
- },
- dismissButton = {
- OutlinedButton(onClick = {
- MainActivity().writeFile(context = activity,dbPath.toUri())
- isDialogShowingState = false
- }) {
- Text(text = "Backup")
- }
- }
- )
+ },
+ onDismissClick = {
+ MainActivity().writeFile(context = activity,dbPath.toUri())
+ })
}
// Backup dialog ends here
ThemeChangerDialog(
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 043142d..48a82a2 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -23,7 +23,7 @@
Oddělte úkoly pomocí datumů
Použít animaci dokončení úkolu
Povolit AutoStart
- Na některých zařízeních nemusí být upozornění přijímána včas nebo po restartu nemusí fungovat. Klepnutím sem povolíte automatické spuštění. \n\n(Užitečné pro Xiaomi, Oppo, vivo a zařízení se stock ROM)
+ Na některých zařízeních nemusí být upozornění přijímána včas nebo po restartu nemusí fungovat. Klepnutím sem povolíte automatické spuštění. Užitečné pro Xiaomi, Oppo, vivo a zařízení se stock ROM
Zobrazit zdrojový kód
Tasky je aplikace s otevřeným zdrojovým kódem. Máte zpětnou vazbu nebo se chcete pustit do vývoje? navštivte Github! A nezapomeňte dát ⭐️ ;)
Použít 24-hodinový čas
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 9348401..d08aa1f 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -23,7 +23,7 @@
Aufgaben trennen durch Verwendung von Daten
Verwendung von Animation bei erfüllter Aufgabe
AutoStart aktivieren
- Bei einigen Geräten kommen die Benachrichtigungen nicht rechtzeitig oder funktionieren nicht nach einer Rebootbenachrichtigung. Klicken Sie hier um autostart zu aktivieren. \n\n(Nützlich für Xiaomi, vivo, Oppo ähnliche Geräte die stock rom verwenden)
+ Bei einigen Geräten kommen die Benachrichtigungen nicht rechtzeitig oder funktionieren nicht nach einer Rebootbenachrichtigung. Klicken Sie hier um autostart zu aktivieren. Nützlich für Xiaomi, vivo, Oppo ähnliche Geräte die stock rom verwenden
Quelle ansehen
Tasky ist komplett quelloffen. Für Rückmeldungen oder Beteiligung an der Entwicklung ? besuchen Sie Github! Oh vergessen Sie nicht mir einen ⭐️ zu geben ;)
24-Stunden-Uhr verwenden
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 7ca6453..114ce86 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -23,7 +23,7 @@
Séparez les tâches en utilisant les dates.
Utilisez complètement les animations.
Activez le démarrage automatique.
- Pour certains appareils, les notifications peuvent ne pas être reçues à temps ou ne pas fonctionner après le redémarrage. Cliquez ici pour activer le démarrage automatique. \n\n(Utile pour Xiaomi, vivo, Oppo comme les appareils exécutant une rom de stockage).
+ Pour certains appareils, les notifications peuvent ne pas être reçues à temps ou ne pas fonctionner après le redémarrage. Cliquez ici pour activer le démarrage automatique. Utile pour Xiaomi, vivo, Oppo comme les appareils exécutant une rom de stockage.
Voir la Source.
Tasky est complètement à source ouverte. Vous avez un retour d expérience ou souhaitez vous lancez dans le développement ? Visitez Github! Oh et n oubliez pas de donnez une ⭐️ ;).
Utiliser l horloge 24 heures.
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 0af04b3..c1e0cde 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -23,7 +23,7 @@
Oddeľte úlohy pomocou dátumov
Použiť animáciu dokončenia úlohy
Povoliť AutoStart
- Na niektorých zariadeniach nemusia byť upozornenia prijímané včas alebo po reštarte nemusia fungovať. Kliknutím sem povolíte automatické spustenie. \n\n(Užitočné pre Xiaomi, Oppo, vivo a zariadenia so stock ROM)
+ Na niektorých zariadeniach nemusia byť upozornenia prijímané včas alebo po reštarte nemusia fungovať. Kliknutím sem povolíte automatické spustenie. Užitočné pre Xiaomi, Oppo, vivo a zariadenia so stock ROM
Zobraziť zdrojový kód
Tasky je aplikácia s otvoreným zdrojovým kódom. Máte spätnú väzbu alebo sa chcete pustiť do vývoja? navštívte Github! A nezabudnite dať ⭐️ ;)
Použiť 24-hodinový čas
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 20055b5..b38e290 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -23,7 +23,7 @@
Görevleri tarihlerine göre ayır
Görev tamamlama animasyonunu etkinleştir
Otomatik Başlatmayı Etkinleştir
- Bazı cihazlarda bildirimler zamanında alınmayabilir veya yeniden başlatıldıktan sonra çalışmayabilir. Otomatik başlatmayı etkinleştirmek için buraya tıklayın. \n\n(Stok rom çalıştıran Xiaomi, vivo, Oppo gibi cihazlar için kullanışlıdır)
+ Bazı cihazlarda bildirimler zamanında alınmayabilir veya yeniden başlatıldıktan sonra çalışmayabilir. Otomatik başlatmayı etkinleştirmek için buraya tıklayın. Stok rom çalıştıran Xiaomi, vivo, Oppo gibi cihazlar için kullanışlıdır
Kaynak kodunu görüntüle
Tasky tamamen açık kaynak kodludur. Bir geri bildiriminiz mi var veya geliştirme sürecine dahil olmak mı istiyorsunuz? Github\'ı ziyaret edin! Ve bir de ⭐️ vermeyi unutmayın ;)
24 Saat Formatı
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ed2e435..863e119 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -23,7 +23,7 @@
Separate tasks using dates
Use task complete animations
Enable AutoStart
- For some devices, notifications might not be received on time, or may not work after reboot. Click here to enable autostart. \n\n(Useful for Xiaomi, Oppo, vivo and devices running stock ROM)
+ For some devices, notifications might not be received on time, or may not work after reboot. Click here to enable autostart. Useful for Xiaomi, Oppo, vivo and devices running stock ROM
View Source
Tasky is completely open source. Have a feedback or want to get into development? visit Github! Oh and don\'t forget to give a ⭐️ ;)
Use 24 Hour Clock