feat: Create/edit logic for new categories

This commit is contained in:
Peter Vacho 2025-01-05 16:40:45 +01:00
parent df18f13972
commit ae2efe89f2
Signed by: school
GPG key ID: 8CFC3837052871B4
2 changed files with 137 additions and 1 deletions

View file

@ -1,17 +1,48 @@
package com.p_vacho.neat_calendar.activities package com.p_vacho.neat_calendar.activities
import android.content.Intent
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.github.dhaval2404.colorpicker.ColorPickerDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.textfield.TextInputEditText
import com.google.gson.Gson
import com.p_vacho.neat_calendar.R import com.p_vacho.neat_calendar.R
import com.p_vacho.neat_calendar.api.RetrofitClient
import com.p_vacho.neat_calendar.api.models.CategoryRequest
import com.p_vacho.neat_calendar.api.models.CategoryResponse
import com.p_vacho.neat_calendar.api.models.PartialCategoryRequest
import com.p_vacho.neat_calendar.api.models.ValidationError
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.HttpException
import kotlin.properties.Delegates
enum class CategoryMode { enum class CategoryMode {
CREATE, EDIT CREATE, EDIT
} }
class CreateCategoryActivity : AppCompatActivity() { class CreateCategoryActivity : AppCompatActivity() {
private var selectedColor by Delegates.notNull<Int>()
private var existingCategory: CategoryResponse? = null
private lateinit var mode: CategoryMode
// UI components
private lateinit var etCategoryName: TextInputEditText
private lateinit var btnColorPicker: MaterialButton
private lateinit var btnSaveCategory: MaterialButton
private lateinit var btnCancel: MaterialButton
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
@ -21,5 +52,107 @@ class CreateCategoryActivity : AppCompatActivity() {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets insets
} }
initializeViews()
mode = intent.getStringExtra("mode")!!.let { CategoryMode.valueOf(it) }
if (mode == CategoryMode.EDIT) {
@Suppress("DEPRECATION")
existingCategory = intent.getParcelableExtra("category")!!
etCategoryName.setText(existingCategory?.name)
selectedColor = existingCategory?.color?.toArgb() ?: ContextCompat.getColor(this, R.color.category_indicator_color)
btnSaveCategory.setText(R.string.update_category)
} else {
selectedColor = ContextCompat.getColor(this, R.color.category_indicator_color)
}
btnColorPicker.iconTint = ColorStateList.valueOf(selectedColor)
setupListeners()
}
private fun initializeViews() {
etCategoryName = findViewById(R.id.etCategoryName)
btnColorPicker = findViewById(R.id.btnColorPicker)
btnSaveCategory = findViewById(R.id.btnSaveCategory)
btnCancel = findViewById(R.id.btnCancel)
}
private fun setupListeners() {
btnColorPicker.setOnClickListener { openColorPickerDialog() }
btnSaveCategory.setOnClickListener { saveCategory() }
btnCancel.setOnClickListener { finish() }
}
private fun saveCategory() {
val categoryName = etCategoryName.text.toString().trim()
if (categoryName.isEmpty()) {
Toast.makeText(this, getString(R.string.please_enter_a_category_name), Toast.LENGTH_SHORT).show()
return
}
lifecycleScope.launch(Dispatchers.IO) {
try {
val resultCategory = if (mode == CategoryMode.CREATE) {
val request =
CategoryRequest(name = categoryName, color = Color.valueOf(selectedColor))
RetrofitClient.categoryService.createCategory(request)
} else {
val request = PartialCategoryRequest(
name = categoryName.takeIf { it != existingCategory?.name },
color = Color.valueOf(selectedColor)
.takeIf { it != existingCategory?.color }
)
RetrofitClient.categoryService.updateCategory(existingCategory!!.id, request)
}
withContext(Dispatchers.Main) { handleCategorySaved(resultCategory) }
} catch (e: HttpException) {
if (e.code() != 422) {
throw e
}
val errorBody = e.response()?.errorBody()?.string()
val validationError = Gson().fromJson(errorBody, ValidationError::class.java)
val errMsg = validationError.detail.joinToString("\n")
Log.e("CategoryCreate", "Got HTTP 422: $validationError")
withContext(Dispatchers.Main) {
Toast.makeText(
this@CreateCategoryActivity,
getString(R.string.failed_to_save_category, errMsg),
Toast.LENGTH_SHORT
).show()
}
}
}
}
private fun handleCategorySaved(category: CategoryResponse) {
Log.w("CreateCategory", "Ending")
val intent = Intent().apply {
if (mode == CategoryMode.CREATE) {
putExtra("newCategory", category)
Log.w("CreateCategory", "New")
} else {
putExtra("editedCategory", category)
Log.w("CreateCategory", "Edit")
}
}
setResult(RESULT_OK, intent)
finish()
}
private fun openColorPickerDialog() {
ColorPickerDialog
.Builder(this)
.setTitle(getString(R.string.select_color))
.setDefaultColor(selectedColor)
.setColorListener { color, _ ->
selectedColor = color
btnColorPicker.iconTint = ColorStateList.valueOf(color)
}
.show()
} }
} }

View file

@ -44,6 +44,7 @@
<string name="remove_category">Remove the category</string> <string name="remove_category">Remove the category</string>
<string name="add_category">Add category</string> <string name="add_category">Add category</string>
<string name="update_event">Update Event</string> <string name="update_event">Update Event</string>
<string name="update_category">Update Category</string>
<string name="leave_invited_event">Leave invited event</string> <string name="leave_invited_event">Leave invited event</string>
<string name="open_app_settings">Open Settings</string> <string name="open_app_settings">Open Settings</string>
<string name="open_notifications">Open Notifications</string> <string name="open_notifications">Open Notifications</string>
@ -97,4 +98,6 @@
<string name="event_owner_section">Event owner:</string> <string name="event_owner_section">Event owner:</string>
<string name="no_invited_categories_placeholder">You can\'t see categories for invited events</string> <string name="no_invited_categories_placeholder">You can\'t see categories for invited events</string>
<string name="edit_category">Edit category</string> <string name="edit_category">Edit category</string>
<string name="please_enter_a_category_name">Please enter a category name</string>
<string name="failed_to_save_category">Failed to save category: %1$s</string>
</resources> </resources>