feat: Add edit button for existing categories
This commit is contained in:
parent
c900c7093f
commit
df18f13972
|
@ -18,7 +18,6 @@ import com.p_vacho.neat_calendar.R
|
||||||
import com.p_vacho.neat_calendar.adapters.CategoryAdapter
|
import com.p_vacho.neat_calendar.adapters.CategoryAdapter
|
||||||
import com.p_vacho.neat_calendar.api.RetrofitClient
|
import com.p_vacho.neat_calendar.api.RetrofitClient
|
||||||
import com.p_vacho.neat_calendar.api.models.CategoryResponse
|
import com.p_vacho.neat_calendar.api.models.CategoryResponse
|
||||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
@ -38,7 +37,12 @@ class CategoriesActivity : AppCompatActivity() {
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
val newCategory: CategoryResponse? = result.data?.getParcelableExtra("newCategory")
|
val newCategory: CategoryResponse? = result.data?.getParcelableExtra("newCategory")
|
||||||
|
|
||||||
newCategory?.let { categoryCreateReply(it) }
|
@Suppress("DEPRECATION")
|
||||||
|
val editedCategory: CategoryResponse? = result.data?.getParcelableExtra("editedCategory")
|
||||||
|
|
||||||
|
if (newCategory != null && editedCategory != null) throw IllegalStateException("Got both edit & new response")
|
||||||
|
if (newCategory != null) categoryCreateReply(newCategory, CategoryMode.CREATE)
|
||||||
|
if (editedCategory != null) categoryCreateReply(editedCategory, CategoryMode.EDIT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +63,14 @@ class CategoriesActivity : AppCompatActivity() {
|
||||||
tvEmptyState = findViewById(R.id.tvEmptyState)
|
tvEmptyState = findViewById(R.id.tvEmptyState)
|
||||||
|
|
||||||
btnBack.setOnClickListener { finish() }
|
btnBack.setOnClickListener { finish() }
|
||||||
btnAddCategory.setOnClickListener { navigateToCreateCategory() }
|
btnAddCategory.setOnClickListener { handleCreateCategory() }
|
||||||
|
|
||||||
rvCategories.layoutManager = LinearLayoutManager(this)
|
rvCategories.layoutManager = LinearLayoutManager(this)
|
||||||
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
categories = fetchCategories().toMutableList()
|
categories = fetchCategories().toMutableList()
|
||||||
|
|
||||||
val adapter = CategoryAdapter(categories, ::handleDeleteCategory)
|
val adapter = CategoryAdapter(categories, ::handleDeleteCategory, ::handleEditCategory)
|
||||||
|
|
||||||
rvCategories.adapter = adapter
|
rvCategories.adapter = adapter
|
||||||
updateEmptyState()
|
updateEmptyState()
|
||||||
|
@ -105,20 +109,44 @@ class CategoriesActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigates to the activity for adding a new category.
|
* Handle create category button getting pressed.
|
||||||
|
*
|
||||||
|
* Navigates to the create category activity in create mode.
|
||||||
*/
|
*/
|
||||||
private fun navigateToCreateCategory() {
|
private fun handleCreateCategory() {
|
||||||
val intent = Intent(this, CreateCategoryActivity::class.java)
|
val intent = Intent(this, CreateCategoryActivity::class.java).apply {
|
||||||
startActivity(intent)
|
putExtra("mode", CategoryMode.CREATE.name)
|
||||||
|
}
|
||||||
|
createActivityLauncher.launch(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle edit category button being pressed.
|
||||||
|
*
|
||||||
|
* Navigates to the create category activity in edit mode.
|
||||||
|
*/
|
||||||
|
private fun handleEditCategory(category: CategoryResponse, position: Int) {
|
||||||
|
val intent = Intent(this, CreateCategoryActivity::class.java).apply {
|
||||||
|
putExtra("mode", CategoryMode.EDIT.name)
|
||||||
|
putExtra("category", category)
|
||||||
|
}
|
||||||
|
createActivityLauncher.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used as a callback, triggered when the CreateCategory Activity returns a result.
|
* Used as a callback, triggered when the CreateCategory Activity returns a result.
|
||||||
*
|
*
|
||||||
* The returned value (the new category data) is passed over as a parameter.
|
* The returned value (the new / edited category data) is passed over as a parameter.
|
||||||
*/
|
*/
|
||||||
private fun categoryCreateReply(category: CategoryResponse) {
|
private fun categoryCreateReply(category: CategoryResponse, mode: CategoryMode) {
|
||||||
(rvCategories.adapter as CategoryAdapter).addCategory(category)
|
val adapter = (rvCategories.adapter as CategoryAdapter)
|
||||||
|
when (mode) {
|
||||||
|
CategoryMode.CREATE -> {
|
||||||
|
adapter.addCategory(category)
|
||||||
|
updateEmptyState()
|
||||||
|
}
|
||||||
|
CategoryMode.EDIT -> { adapter.editCategory(category) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,6 +7,10 @@ import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import com.p_vacho.neat_calendar.R
|
import com.p_vacho.neat_calendar.R
|
||||||
|
|
||||||
|
enum class CategoryMode {
|
||||||
|
CREATE, EDIT
|
||||||
|
}
|
||||||
|
|
||||||
class CreateCategoryActivity : AppCompatActivity() {
|
class CreateCategoryActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
|
@ -11,12 +11,14 @@ import com.p_vacho.neat_calendar.api.models.CategoryResponse
|
||||||
|
|
||||||
class CategoryAdapter(
|
class CategoryAdapter(
|
||||||
private val categories: MutableList<CategoryResponse>,
|
private val categories: MutableList<CategoryResponse>,
|
||||||
private val onDeleteClick: (CategoryResponse, Int) -> Unit
|
private val onDeleteClick: (CategoryResponse, Int) -> Unit,
|
||||||
|
private val onEditClick: (CategoryResponse, Int) -> Unit
|
||||||
) : RecyclerView.Adapter<CategoryAdapter.CategoryViewHolder>() {
|
) : RecyclerView.Adapter<CategoryAdapter.CategoryViewHolder>() {
|
||||||
|
|
||||||
inner class CategoryViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
inner class CategoryViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
val colorIndicator: View = view.findViewById(R.id.colorIndicator)
|
val colorIndicator: View = view.findViewById(R.id.colorIndicator)
|
||||||
val categoryName: TextView = view.findViewById(R.id.tvCategoryName)
|
val categoryName: TextView = view.findViewById(R.id.tvCategoryName)
|
||||||
|
val editButton: ImageButton = view.findViewById(R.id.btnEditCategory)
|
||||||
val deleteButton: ImageButton = view.findViewById(R.id.btnDeleteCategory)
|
val deleteButton: ImageButton = view.findViewById(R.id.btnDeleteCategory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +35,9 @@ class CategoryAdapter(
|
||||||
holder.colorIndicator.setBackgroundColor(category.color.toArgb())
|
holder.colorIndicator.setBackgroundColor(category.color.toArgb())
|
||||||
holder.categoryName.text = category.name
|
holder.categoryName.text = category.name
|
||||||
|
|
||||||
// Set click listener for the delete button
|
// Set click listeners for the buttons
|
||||||
holder.deleteButton.setOnClickListener {
|
holder.deleteButton.setOnClickListener { onDeleteClick(category, position) }
|
||||||
onDeleteClick(category, position)
|
holder.editButton.setOnClickListener { onEditClick(category, position) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = categories.size
|
override fun getItemCount(): Int = categories.size
|
||||||
|
@ -64,4 +65,15 @@ class CategoryAdapter(
|
||||||
categories.add(category)
|
categories.add(category)
|
||||||
notifyItemInserted(categories.size)
|
notifyItemInserted(categories.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edit an existing category, updating it in the UI.
|
||||||
|
*
|
||||||
|
* Call this after the onEditClick callback edits the category from the backend API.
|
||||||
|
*/
|
||||||
|
fun editCategory(category: CategoryResponse) {
|
||||||
|
val position = categories.indexOfFirst { it.id == category.id }
|
||||||
|
categories[position] = category
|
||||||
|
notifyItemChanged(position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,28 @@
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@id/colorIndicator"
|
app:layout_constraintStart_toEndOf="@id/colorIndicator"
|
||||||
app:layout_constraintEnd_toStartOf="@id/btnDeleteCategory" />
|
app:layout_constraintEnd_toStartOf="@id/buttonContainer" />
|
||||||
|
|
||||||
|
<!-- Button Container -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/buttonContainer"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent">
|
||||||
|
|
||||||
|
<!-- Edit Button -->
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/btnEditCategory"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
|
android:src="@drawable/ic_pencil"
|
||||||
|
android:contentDescription="@string/edit_category"
|
||||||
|
app:tint="?android:attr/textColorSecondary" />
|
||||||
|
|
||||||
<!-- Delete Button -->
|
<!-- Delete Button -->
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
@ -50,10 +71,8 @@
|
||||||
android:background="?attr/selectableItemBackgroundBorderless"
|
android:background="?attr/selectableItemBackgroundBorderless"
|
||||||
android:src="@drawable/ic_trashbin"
|
android:src="@drawable/ic_trashbin"
|
||||||
android:contentDescription="@string/delete_category"
|
android:contentDescription="@string/delete_category"
|
||||||
app:tint="?android:attr/textColorSecondary"
|
app:tint="?android:attr/textColorSecondary" />
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
</LinearLayout>
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.cardview.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
|
@ -96,4 +96,5 @@
|
||||||
<string name="no_categories_placeholder">This event has no categories.</string>
|
<string name="no_categories_placeholder">This event has no categories.</string>
|
||||||
<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>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in a new issue