From 78f2037f04da64ba2fe62ab039439da75a468cf1 Mon Sep 17 00:00:00 2001 From: Merango Date: Sat, 5 Jul 2025 10:11:47 +0000 Subject: [PATCH 1/4] Start draft PR From 7a6247b6bf0c567828aa9553cd0b8ccd840a53d8 Mon Sep 17 00:00:00 2001 From: Merango Date: Sat, 5 Jul 2025 10:13:22 +0000 Subject: [PATCH 2/4] Add basic unit tests for TodoViewModel --- .gitignore | 60 +- .../java/com/todoapp/ui/EditTodoActivity.kt | 111 + .../main/res/layout/activity_edit_todo.xml | 64 +- .../todoapp/viewmodel/TodoViewModelTest.kt | 60 + package-lock.json | 4397 +++++++++++++++++ package.json | 5 + 6 files changed, 4680 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/com/todoapp/ui/EditTodoActivity.kt create mode 100644 app/src/test/java/com/todoapp/viewmodel/TodoViewModelTest.kt create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 1f8751e..c770223 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,22 @@ *.iml .gradle /local.properties +<<<<<<< HEAD /.idea/ +======= +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +>>>>>>> pr-7-Santix1234-kotlinTodoApp .DS_Store /build /captures .externalNativeBuild .cxx +<<<<<<< HEAD # Gradle files *.gradle @@ -45,4 +55,52 @@ release/ # Secrets and local configs *.env -local.properties \ No newline at end of file +local.properties +======= +local.properties + +# Kotlin/Android +bin/ +gen/ +out/ +*.class +*.log +*.dex +*.apk + +# Dependency directories +node_modules/ +jspm_packages/ +app/libs/ + +# Gradle +.gradle/ +build/ + +# Testing +app/build/ +app/test/ +app/androidTest/ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Virtual environment +venv/ +.env + +# IDE specific files +.vscode/ +.idea/ +*.ipr +*.iws + +# Misc +*.swp +*.swo +.DS_Store +>>>>>>> pr-7-Santix1234-kotlinTodoApp diff --git a/app/src/main/java/com/todoapp/ui/EditTodoActivity.kt b/app/src/main/java/com/todoapp/ui/EditTodoActivity.kt new file mode 100644 index 0000000..47301f5 --- /dev/null +++ b/app/src/main/java/com/todoapp/ui/EditTodoActivity.kt @@ -0,0 +1,111 @@ +package com.todoapp.ui + +import android.os.Bundle +import android.widget.Button +import android.widget.EditText +import android.widget.Switch +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import com.todoapp.R +import com.todoapp.data.Todo +import com.todoapp.viewmodel.TodoViewModel +import kotlinx.coroutines.launch + +class EditTodoActivity : AppCompatActivity() { + + private lateinit var todoViewModel: TodoViewModel + private lateinit var titleEditText: EditText + private lateinit var descriptionEditText: EditText + private lateinit var completedSwitch: Switch + private lateinit var saveButton: Button + private lateinit var cancelButton: Button + + private var todoId: Long = -1 + + companion object { + const val EXTRA_TODO_ID = "extra_todo_id" + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_edit_todo) + + // Initialize ViewModel + todoViewModel = ViewModelProvider(this)[TodoViewModel::class.java] + + // Initialize views + titleEditText = findViewById(R.id.edit_todo_title) + descriptionEditText = findViewById(R.id.edit_todo_description) + completedSwitch = findViewById(R.id.edit_todo_completed_switch) + saveButton = findViewById(R.id.save_todo_button) + cancelButton = findViewById(R.id.cancel_todo_button) + + // Get todo item ID from intent + todoId = intent.getLongExtra(EXTRA_TODO_ID, -1) + + // Load existing todo item if editing + if (todoId != -1L) { + loadTodoItem() + } + + // Save button click listener + saveButton.setOnClickListener { + saveTodoItem() + } + + // Cancel button click listener + cancelButton.setOnClickListener { + finish() + } + } + + private fun loadTodoItem() { + lifecycleScope.launch { + val todo = todoViewModel.getTodoById(todoId) + todo?.let { + titleEditText.setText(it.title) + descriptionEditText.setText(it.description) + completedSwitch.isChecked = it.isCompleted + } + } + } + + private fun saveTodoItem() { + val title = titleEditText.text.toString().trim() + val description = descriptionEditText.text.toString().trim() + val isCompleted = completedSwitch.isChecked + + // Validate input + if (title.isEmpty()) { + titleEditText.error = "Title cannot be empty" + return + } + + lifecycleScope.launch { + try { + // Create or update todo item + val todo = Todo( + id = if (todoId == -1L) 0 else todoId, + title = title, + description = description, + isCompleted = isCompleted + ) + + if (todoId == -1L) { + todoViewModel.insertTodo(todo) + Toast.makeText(this@EditTodoActivity, "Todo created", Toast.LENGTH_SHORT).show() + } else { + todoViewModel.updateTodo(todo) + Toast.makeText(this@EditTodoActivity, "Todo updated", Toast.LENGTH_SHORT).show() + } + + // Close the activity + finish() + } catch (e: Exception) { + Toast.makeText(this@EditTodoActivity, "Error saving todo", Toast.LENGTH_SHORT).show() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit_todo.xml b/app/src/main/res/layout/activity_edit_todo.xml index 9ab416b..37993d6 100644 --- a/app/src/main/res/layout/activity_edit_todo.xml +++ b/app/src/main/res/layout/activity_edit_todo.xml @@ -12,17 +12,19 @@ android:id="@+id/titleInputLayout" android:layout_width="0dp" android:layout_height="wrap_content" - android:hint="Title" + android:hint="Todo Title" + android:layout_marginBottom="8dp" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent"> + android:maxLines="1" + tools:text="Buy groceries"/> + android:maxLines="5" + tools:text="Buy milk, eggs, and bread"/> - + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent"> + + - + + + + android:layout_marginBottom="16dp"> + +