feat: Fetch calendar events from api
This commit is contained in:
parent
82b3614920
commit
b3c386a9dc
|
@ -1,5 +1,6 @@
|
|||
package com.p_vacho.neat_calendar.activities
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
|
@ -9,19 +10,28 @@ import androidx.core.view.ViewCompat
|
|||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.p_vacho.neat_calendar.MyApplication
|
||||
import com.p_vacho.neat_calendar.R
|
||||
import com.p_vacho.neat_calendar.adapters.CalendarAdapter
|
||||
import com.p_vacho.neat_calendar.api.RetrofitClient
|
||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||
import com.p_vacho.neat_calendar.models.CalendarDay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.ZoneOffset
|
||||
import java.time.YearMonth
|
||||
import java.time.format.TextStyle
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
class CalendarActivity : AppCompatActivity() {
|
||||
private lateinit var tvMonthYear: TextView
|
||||
private lateinit var rvCalendar: RecyclerView
|
||||
private lateinit var btnPreviousMonth: ImageButton
|
||||
private lateinit var btnNextMonth: ImageButton
|
||||
|
||||
private val tokenManager by lazy { (application as MyApplication).tokenManager }
|
||||
|
||||
private var currentYearMonth: YearMonth = YearMonth.now()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
@ -52,36 +62,88 @@ class CalendarActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setCalendarForMonth(yearMonth: YearMonth) {
|
||||
val firstDayOfMonth = yearMonth.atDay(1)
|
||||
val daysInMonth = yearMonth.lengthOfMonth()
|
||||
/**
|
||||
* Obtain all of the events that occur for each day in the given month from the API.
|
||||
*
|
||||
* The returned structure is a hashmap with int keys, being the day numbers in the month.
|
||||
* If an event spans multiple days, it will be added for each of those days.
|
||||
*/
|
||||
private suspend fun fetchEventsForMonth(yearMonth: YearMonth): Map<Int, List<EventResponse>> {
|
||||
val startFrom = yearMonth.atDay(1).atStartOfDay().atOffset(ZoneOffset.UTC)
|
||||
val endTo = yearMonth.atEndOfMonth().atTime(23, 59, 59).atOffset(ZoneOffset.UTC)
|
||||
|
||||
// TODO: Replace with an API call to obtain the events
|
||||
val eventDays = setOf(3, 15, 20)
|
||||
val userId = tokenManager.userId
|
||||
|
||||
// Get localized month name and year
|
||||
val monthYearText = "${yearMonth.month.getDisplayName(TextStyle.FULL, Locale.getDefault())} ${yearMonth.year}"
|
||||
tvMonthYear.text = monthYearText
|
||||
|
||||
// Calculate the amount of placeholder slots until the first day in the month
|
||||
// (Our calendar starts from Monday, but not all months start on monday, so we need fillers)
|
||||
val startOffset = firstDayOfMonth.dayOfWeek.ordinal // Gives 0 (Monday) to 6 (Sunday)
|
||||
|
||||
// Generate calendar days
|
||||
val days = mutableListOf<CalendarDay>()
|
||||
|
||||
// Add padding for days of the previous month
|
||||
for (i in 1..startOffset) {
|
||||
days.add(CalendarDay(dayNumber = ""))
|
||||
if (userId.isNullOrEmpty()) {
|
||||
navigateToMainActivity()
|
||||
return emptyMap()
|
||||
}
|
||||
|
||||
// Add the actual days of the current month
|
||||
for (i in 1..daysInMonth) {
|
||||
days.add(CalendarDay(dayNumber = i.toString(), hasEvents = eventDays.contains(i)))
|
||||
val events = RetrofitClient.eventsService.userEvents(
|
||||
userId = userId,
|
||||
startFrom = startFrom,
|
||||
endTo = endTo
|
||||
)
|
||||
|
||||
// Create a mapping of days to events
|
||||
val eventsByDay = mutableMapOf<Int, MutableList<EventResponse>>()
|
||||
|
||||
for (event in events) {
|
||||
val startDay = maxOf(event.start_time.dayOfMonth, 1)
|
||||
val endDay = minOf(event.end_time.dayOfMonth, yearMonth.lengthOfMonth())
|
||||
|
||||
for (day in startDay..endDay) {
|
||||
eventsByDay.computeIfAbsent(day) { mutableListOf() }.add(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Set up RecyclerView
|
||||
rvCalendar.layoutManager = GridLayoutManager(this, 7) // 7 columns for days of the week
|
||||
rvCalendar.adapter = CalendarAdapter(days)
|
||||
return eventsByDay
|
||||
}
|
||||
|
||||
private fun setCalendarForMonth(yearMonth: YearMonth) {
|
||||
lifecycleScope.launch {
|
||||
val firstDayOfMonth = yearMonth.atDay(1)
|
||||
val daysInMonth = yearMonth.lengthOfMonth()
|
||||
|
||||
val eventsByDay = fetchEventsForMonth(yearMonth)
|
||||
|
||||
// Get localized month name and year
|
||||
val monthYearText = "${
|
||||
yearMonth.month.getDisplayName(
|
||||
TextStyle.FULL,
|
||||
Locale.getDefault()
|
||||
)
|
||||
} ${yearMonth.year}"
|
||||
tvMonthYear.text = monthYearText
|
||||
|
||||
// Calculate the amount of placeholder slots until the first day in the month
|
||||
// (Our calendar starts from Monday, but not all months start on monday, so we need fillers)
|
||||
val startOffset = firstDayOfMonth.dayOfWeek.ordinal // Gives 0 (Monday) to 6 (Sunday)
|
||||
|
||||
// Generate calendar days
|
||||
val days = mutableListOf<CalendarDay>()
|
||||
|
||||
// Add padding for days of the previous month
|
||||
for (i in 1..startOffset) {
|
||||
days.add(CalendarDay(dayNumber = ""))
|
||||
}
|
||||
|
||||
// Add the actual days of the current month
|
||||
for (i in 1..daysInMonth) {
|
||||
val eventsForDay = eventsByDay[i] ?: emptyList()
|
||||
days.add(CalendarDay(dayNumber = i.toString(), hasEvents = eventsForDay.isNotEmpty())) }
|
||||
|
||||
// Set up RecyclerView
|
||||
rvCalendar.layoutManager = GridLayoutManager(this@CalendarActivity, 7) // 7 columns for days of the week
|
||||
rvCalendar.adapter = CalendarAdapter(days)
|
||||
}
|
||||
}
|
||||
|
||||
private fun navigateToMainActivity() {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivity(intent)
|
||||
finish() // Close the login screen
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import retrofit2.HttpException
|
|||
import java.io.IOException
|
||||
import java.time.OffsetDateTime
|
||||
import com.fatboyindustrial.gsonjavatime.OffsetDateTimeConverter
|
||||
import com.p_vacho.neat_calendar.api.services.EventsService
|
||||
|
||||
object RetrofitClient {
|
||||
private const val DEFAULT_BASE_URL = "http://10.0.2.2:8000"
|
||||
|
@ -30,6 +31,10 @@ object RetrofitClient {
|
|||
val generalService: GeneralService
|
||||
get() = retrofitWithReachability!!.create(GeneralService::class.java)
|
||||
|
||||
val eventsService: EventsService
|
||||
get() = retrofitWithReachability!!.create(EventsService::class.java)
|
||||
|
||||
|
||||
fun initialize(context: Context) {
|
||||
appContext = context
|
||||
baseUrl = getBaseUrl()
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package com.p_vacho.neat_calendar.api.models
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
data class EventResponse(
|
||||
val id: String,
|
||||
val title: String,
|
||||
val description: String,
|
||||
val category_ids: List<String>,
|
||||
val start_time: OffsetDateTime,
|
||||
val end_time: OffsetDateTime,
|
||||
val color: String, // Hex color (e.g., #ff0000)
|
||||
val owner_user_id: String,
|
||||
val attendee_ids: List<String>,
|
||||
val created_at: OffsetDateTime
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
package com.p_vacho.neat_calendar.api.services
|
||||
|
||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Path
|
||||
import retrofit2.http.Query
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
interface EventsService {
|
||||
@GET("events/{event_id}")
|
||||
suspend fun getEvent(@Path("event_id") eventId: String): EventResponse
|
||||
|
||||
@GET("users/{user_id}/events")
|
||||
suspend fun userEvents(
|
||||
@Path("user_id") userId: String,
|
||||
@Query("start_from") startFrom: OffsetDateTime? = null,
|
||||
@Query("start_to") startTo: OffsetDateTime? = null,
|
||||
@Query("end_from") endFrom: OffsetDateTime? = null,
|
||||
@Query("end_to") endTo: OffsetDateTime? = null
|
||||
): List<EventResponse>
|
||||
|
||||
@GET("users/{user_id}/events/invited")
|
||||
suspend fun userEventsInvited(
|
||||
@Path("user_id") userId: String,
|
||||
@Query("start_from") startFrom: OffsetDateTime? = null,
|
||||
@Query("start_to") startTo: OffsetDateTime? = null,
|
||||
@Query("end_from") endFrom: OffsetDateTime? = null,
|
||||
@Query("end_to") endTo: OffsetDateTime? = null
|
||||
): List<EventResponse>}
|
Loading…
Reference in a new issue