feat: Very basic day view with the day's events
This commit is contained in:
parent
0b6546c269
commit
5620bd4277
|
@ -1,6 +1,7 @@
|
|||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
id("kotlin-parcelize")
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.NeatCalendar"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".activities.DayViewActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".activities.CalendarActivity"
|
||||
android:exported="false" />
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.p_vacho.neat_calendar.activities
|
|||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.ImageButton
|
||||
import android.widget.TextView
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
|
@ -140,11 +141,12 @@ class CalendarActivity : AppCompatActivity() {
|
|||
// 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())) }
|
||||
days.add(CalendarDay(dayNumber = i.toString(), eventsForDay))
|
||||
}
|
||||
|
||||
// Set up RecyclerView
|
||||
rvCalendar.layoutManager = GridLayoutManager(this@CalendarActivity, 7) // 7 columns for days of the week
|
||||
rvCalendar.adapter = CalendarAdapter(days)
|
||||
rvCalendar.adapter = CalendarAdapter(days) { day -> navigateToDayActivity(day) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,4 +157,21 @@ class CalendarActivity : AppCompatActivity() {
|
|||
finish() // Close the login screen
|
||||
}
|
||||
|
||||
private fun navigateToDayActivity(day: CalendarDay) {
|
||||
// TODO: Handle the placeholder days in a better way, using an empty string
|
||||
// feels very odd.
|
||||
if (day.dayNumber.isEmpty()) {
|
||||
Log.w("Calendar", "User clicked on placeholder value")
|
||||
return
|
||||
}
|
||||
|
||||
var intent = Intent(this, DayViewActivity::class.java)
|
||||
intent.putParcelableArrayListExtra(
|
||||
"events", ArrayList(day.events)
|
||||
)
|
||||
val formattedDate = currentYearMonth.atDay(day.dayNumber.toInt()).toString()
|
||||
intent.putExtra("date", formattedDate)
|
||||
startActivity(intent)
|
||||
// Don't finish the current activity, we want to be able to go back here
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package com.p_vacho.neat_calendar.activities
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.TextView
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.p_vacho.neat_calendar.R
|
||||
import com.p_vacho.neat_calendar.adapters.EventAdapter
|
||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||
|
||||
class DayViewActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContentView(R.layout.activity_day_view)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
||||
insets
|
||||
}
|
||||
|
||||
val date = intent.getStringExtra("date")!!
|
||||
|
||||
// The getParcelableArrayListExtra wants the class as a second argument to
|
||||
// be more type-safe, but this is only supported since api 33, which is over
|
||||
// our min api version, so we can ignore this deprecation for now.
|
||||
@Suppress("DEPRECATION")
|
||||
val events = intent.getParcelableArrayListExtra<EventResponse>("events")!!
|
||||
|
||||
val tvDate: TextView = findViewById(R.id.tvDate)
|
||||
val rvEvents: RecyclerView = findViewById(R.id.rvEvents)
|
||||
|
||||
// Set up UI
|
||||
tvDate.text = date
|
||||
rvEvents.layoutManager = LinearLayoutManager(this)
|
||||
rvEvents.adapter = EventAdapter(events)
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import com.p_vacho.neat_calendar.R
|
||||
import com.p_vacho.neat_calendar.models.CalendarDay
|
||||
|
||||
class CalendarAdapter(private val days: List<CalendarDay>) :
|
||||
class CalendarAdapter(private val days: List<CalendarDay>, private val onDayClicked: (CalendarDay) -> Unit) :
|
||||
RecyclerView.Adapter<CalendarAdapter.DayViewHolder>() {
|
||||
|
||||
class DayViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
@ -28,11 +28,16 @@ class CalendarAdapter(private val days: List<CalendarDay>) :
|
|||
holder.tvDay.text = day.dayNumber
|
||||
|
||||
// Visually indicate days with events
|
||||
if (day.hasEvents) {
|
||||
if (day.events.isNotEmpty()) {
|
||||
holder.tvDay.setBackgroundResource(R.drawable.event_indicator_background)
|
||||
} else {
|
||||
holder.tvDay.setBackgroundResource(android.R.color.transparent)
|
||||
}
|
||||
|
||||
// Trigger the click listener with the clicked day
|
||||
holder.itemView.setOnClickListener {
|
||||
onDayClicked(day)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = days.size
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package com.p_vacho.neat_calendar.adapters
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.p_vacho.neat_calendar.R
|
||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||
|
||||
class EventAdapter(private val events: List<EventResponse>) :
|
||||
RecyclerView.Adapter<EventAdapter.EventViewHolder>() {
|
||||
|
||||
class EventViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val tvTitle: TextView = itemView.findViewById(R.id.tvTitle)
|
||||
val tvDescription: TextView = itemView.findViewById(R.id.tvDescription)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_event, parent, false)
|
||||
return EventViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: EventViewHolder, position: Int) {
|
||||
val event = events[position]
|
||||
holder.tvTitle.text = event.title
|
||||
holder.tvDescription.text = event.description
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = events.size
|
||||
}
|
|
@ -1,7 +1,10 @@
|
|||
package com.p_vacho.neat_calendar.api.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
@Parcelize
|
||||
data class EventResponse(
|
||||
val id: String,
|
||||
val title: String,
|
||||
|
@ -13,4 +16,4 @@ data class EventResponse(
|
|||
val owner_user_id: String,
|
||||
val attendee_ids: List<String>,
|
||||
val created_at: OffsetDateTime
|
||||
)
|
||||
): Parcelable
|
|
@ -1,6 +1,11 @@
|
|||
package com.p_vacho.neat_calendar.models
|
||||
|
||||
import android.os.Parcelable
|
||||
import com.p_vacho.neat_calendar.api.models.EventResponse
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class CalendarDay(
|
||||
val dayNumber: String, // Day of the month (e.g., "1", "2", ...)
|
||||
val hasEvents: Boolean = false
|
||||
)
|
||||
val dayNumber: String,
|
||||
val events: List<EventResponse> = emptyList() // Add this property
|
||||
): Parcelable
|
26
app/src/main/res/layout/activity_day_view.xml
Normal file
26
app/src/main/res/layout/activity_day_view.xml
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
tools:context=".activities.DayViewActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_gravity="center"
|
||||
tools:text="2025-01-01"/>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvEvents"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</LinearLayout>
|
22
app/src/main/res/layout/item_event.xml
Normal file
22
app/src/main/res/layout/item_event.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:paddingTop="4dp" />
|
||||
</LinearLayout>
|
Loading…
Reference in a new issue