feat: Fetch categories from the API

This commit is contained in:
Peter Vacho 2024-12-31 01:24:07 +01:00
parent 7dffeda7a6
commit 8c7fffca6f
Signed by: school
GPG key ID: 8CFC3837052871B4
6 changed files with 74 additions and 24 deletions

View file

@ -36,6 +36,6 @@ class DayViewActivity : AppCompatActivity() {
tvDate.text = calendarDay.date.toString()
rvEvents.layoutManager = LinearLayoutManager(this)
rvEvents.adapter = EventCardAdapter(calendarDay.events)
rvEvents.adapter = EventCardAdapter(calendarDay.events, this)
}
}

View file

@ -7,12 +7,11 @@ import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.p_vacho.neat_calendar.R
import androidx.core.content.ContextCompat
import com.p_vacho.neat_calendar.api.models.CategoryResponse
class CategoryChipAdapter(private val categories: List<CategoryItem>) :
class CategoryChipAdapter(private val categories: List<CategoryResponse>) :
RecyclerView.Adapter<CategoryChipAdapter.CategoryViewHolder>() {
data class CategoryItem(val id: Int, val name: String, val color: Color)
inner class CategoryViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategoryViewHolder {

View file

@ -5,16 +5,25 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.p_vacho.neat_calendar.R
import com.p_vacho.neat_calendar.api.RetrofitClient
import com.p_vacho.neat_calendar.api.models.EventResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Locale
class EventCardAdapter(private val events: List<EventResponse>) :
class EventCardAdapter(
private val events: List<EventResponse>,
private val lifecycleOwner: LifecycleOwner
) :
RecyclerView.Adapter<EventCardAdapter.EventViewHolder>() {
inner class EventViewHolder(view: View) : RecyclerView.ViewHolder(view) {
@ -46,25 +55,13 @@ class EventCardAdapter(private val events: List<EventResponse>) :
holder.tvDescription.text = event.description
}
// TODO: Fetch the categoreis for this event from the API
val categories = listOf(
CategoryChipAdapter.CategoryItem(id = 1, name = "Work", color = Color.valueOf(Color.parseColor("#33A733"))), // Red
CategoryChipAdapter.CategoryItem(id = 2, name = "Personal", color = Color.valueOf(Color.parseColor("#3498DB"))), // Blue
CategoryChipAdapter.CategoryItem(id = 3, name = "Urgent", color = Color.valueOf(Color.parseColor("#E74C3C"))), // Bright Red
CategoryChipAdapter.CategoryItem(id = 4, name = "Fitness", color = Color.valueOf(Color.parseColor("#FFB400"))), // Orange
CategoryChipAdapter.CategoryItem(id = 5, name = "Travel", color = Color.valueOf(Color.parseColor("#7D3C98"))), // Purple
CategoryChipAdapter.CategoryItem(id = 6, name = "Shopping", color = Color.valueOf(Color.parseColor("#85C1E9"))), // Light Blue
CategoryChipAdapter.CategoryItem(id = 7, name = "Finance", color = Color.valueOf(Color.parseColor("#2ECC71"))), // Bright Green
CategoryChipAdapter.CategoryItem(id = 8, name = "Health", color = Color.valueOf(Color.parseColor("#F39C12"))), // Gold
CategoryChipAdapter.CategoryItem(id = 9, name = "Meetings", color = Color.valueOf(Color.parseColor("#C0392B"))), // Crimson
CategoryChipAdapter.CategoryItem(id = 10, name = "Hobbies", color = Color.valueOf(Color.parseColor("#8E44AD"))), // Deep Purple
CategoryChipAdapter.CategoryItem(id = 11, name = "Study", color = Color.valueOf(Color.parseColor("#1ABC9C"))), // Teal
CategoryChipAdapter.CategoryItem(id = 12, name = "Events", color = Color.valueOf(Color.parseColor("#34495E"))), // Navy Blue
)
// Initialize empty state for categories
holder.rvCategories.layoutManager =
LinearLayoutManager(holder.itemView.context, LinearLayoutManager.HORIZONTAL, false)
holder.rvCategories.adapter = CategoryChipAdapter(categories)
holder.rvCategories.adapter = CategoryChipAdapter(emptyList())
// Fetch categories dynamically
fetchAndBindCategories(event.id, holder)
}
override fun getItemCount(): Int = events.size
@ -90,4 +87,20 @@ class EventCardAdapter(private val events: List<EventResponse>) :
}
}
}
/**
* Fetches all categories for given event and bind them to the recycler view.
*/
private fun fetchAndBindCategories(eventId: String, holder: EventViewHolder) {
// Use the lifecycleOwner's scope to launch the coroutine
lifecycleOwner.lifecycleScope.launch {
// Fetch categories in the IO dispatcher
val categories = withContext(Dispatchers.IO) {
RetrofitClient.categoryService.eventCategories(eventId)
}
// Update the RecyclerView adapter on the main thread
holder.rvCategories.adapter = CategoryChipAdapter(categories)
}
}
}

View file

@ -10,11 +10,10 @@ import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import com.p_vacho.neat_calendar.api.interceptors.AuthInterceptor
import okhttp3.ResponseBody
import retrofit2.HttpException
import java.time.OffsetDateTime
import com.fatboyindustrial.gsonjavatime.OffsetDateTimeConverter
import com.p_vacho.neat_calendar.api.converters.ColorConverter
import com.p_vacho.neat_calendar.api.services.CategoryService
import com.p_vacho.neat_calendar.api.services.EventsService
object RetrofitClient {
@ -23,6 +22,7 @@ object RetrofitClient {
private var baseUrl: String = DEFAULT_BASE_URL
private lateinit var appContext: Context
// TODO: Make this lateinit
private var retrofitClient: Retrofit? = null
val authService: AuthService
@ -34,6 +34,10 @@ object RetrofitClient {
val eventsService: EventsService
get() = retrofitClient!!.create(EventsService::class.java)
val categoryService: CategoryService
get() = retrofitClient!!.create(CategoryService::class.java)
fun initialize(context: Context) {
appContext = context

View file

@ -0,0 +1,18 @@
package com.p_vacho.neat_calendar.api.models
import android.graphics.Color
import android.os.Parcelable
import com.p_vacho.neat_calendar.api.converters.ColorParceler
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.TypeParceler
import java.time.OffsetDateTime
@Parcelize
@TypeParceler<Color, ColorParceler>
data class CategoryResponse(
val id: String,
val name: String,
val color: Color,
val owner_user_id: String,
val created_at: OffsetDateTime
): Parcelable

View file

@ -0,0 +1,16 @@
package com.p_vacho.neat_calendar.api.services
import com.p_vacho.neat_calendar.api.models.CategoryResponse
import retrofit2.http.GET
import retrofit2.http.Path
interface CategoryService {
@GET("/users/{user_id}/categories")
suspend fun userCategories(@Path("user_id") userId: String): List<CategoryResponse>
@GET("/events/{event_id}/categories")
suspend fun eventCategories(@Path("event_id") eventId: String): List<CategoryResponse>
@GET("/category/{category_id}")
suspend fun getCategory(@Path("category_id") categoryId: String): CategoryResponse
}