Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions app/src/main/java/com/travelmeet/app/ui/feed/FeedFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,25 @@ import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.travelmeet.app.R
import com.travelmeet.app.data.local.entity.SpotEntity
import com.travelmeet.app.databinding.FragmentFeedBinding
import com.travelmeet.app.ui.viewmodel.SpotViewModel
import com.travelmeet.app.util.Resource
import kotlin.math.min

class FeedFragment : Fragment() {

companion object {
private const val PAGE_SIZE = 5
}

private var _binding: FragmentFeedBinding? = null
private val binding get() = _binding!!
private val spotViewModel: SpotViewModel by activityViewModels()
private lateinit var spotAdapter: SpotAdapter
private lateinit var feedLayoutManager: LinearLayoutManager
private var pagedSpots: List<SpotEntity> = emptyList()
private var currentPage = 0

override fun onCreateView(
inflater: LayoutInflater,
Expand Down Expand Up @@ -50,9 +59,28 @@ class FeedFragment : Fragment() {
spotViewModel.toggleLike(spot.id)
}
)
feedLayoutManager = LinearLayoutManager(requireContext())
binding.rvSpots.apply {
adapter = spotAdapter
layoutManager = LinearLayoutManager(requireContext())
layoutManager = feedLayoutManager
}
setupPaginationControls()
}

private fun setupPaginationControls() {
binding.btnNextPage.setOnClickListener {
if (canGoNext()) {
currentPage++
submitFeedPage()
binding.rvSpots.scrollToPosition(0)
}
}
binding.btnPrevPage.setOnClickListener {
if (currentPage > 0) {
currentPage--
submitFeedPage()
binding.rvSpots.scrollToPosition(0)
}
}
}

Expand All @@ -65,11 +93,18 @@ class FeedFragment : Fragment() {
}

private fun observeSpots() {
// Observe cached spots from Room
spotViewModel.allSpots.observe(viewLifecycleOwner) { spots ->
spotAdapter.submitList(spots)
binding.emptyState.visibility = if (spots.isEmpty()) View.VISIBLE else View.GONE
binding.rvSpots.visibility = if (spots.isEmpty()) View.GONE else View.VISIBLE
pagedSpots = spots
currentPage = 0
val isEmpty = spots.isEmpty()
binding.emptyState.visibility = if (isEmpty) View.VISIBLE else View.GONE
binding.rvSpots.visibility = if (isEmpty) View.GONE else View.VISIBLE
if (isEmpty) {
spotAdapter.submitList(emptyList())
updatePaginationUi(0)
} else {
submitFeedPage()
}
}

// Observe sync state
Expand Down Expand Up @@ -100,6 +135,41 @@ class FeedFragment : Fragment() {
}
}

private fun canGoNext(): Boolean {
val pages = totalPages()
return pages > 0 && currentPage < pages - 1
}

private fun submitFeedPage() {
val pages = totalPages()
if (pages == 0) {
spotAdapter.submitList(emptyList())
updatePaginationUi(pages)
return
}
if (currentPage >= pages) currentPage = pages - 1
val startIndex = currentPage * PAGE_SIZE
val endIndex = min(startIndex + PAGE_SIZE, pagedSpots.size)
val subList = pagedSpots.subList(startIndex, endIndex)
spotAdapter.submitList(ArrayList(subList))
updatePaginationUi(pages)
}

private fun totalPages(): Int =
if (pagedSpots.isEmpty()) 0 else ((pagedSpots.size - 1) / PAGE_SIZE) + 1

private fun updatePaginationUi(pages: Int) {
val showPagination = pagedSpots.size > PAGE_SIZE
binding.paginationContainer.visibility = if (showPagination) View.VISIBLE else View.GONE
binding.btnPrevPage.isEnabled = showPagination && currentPage > 0
binding.btnNextPage.isEnabled = showPagination && currentPage < pages - 1
binding.tvPageIndicator.text = if (pages == 0) {
getString(R.string.page_indicator, 0, 0)
} else {
getString(R.string.page_indicator, currentPage + 1, pages)
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
Expand Down
79 changes: 75 additions & 4 deletions app/src/main/java/com/travelmeet/app/ui/profile/MySpotsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.travelmeet.app.R
import com.travelmeet.app.data.local.entity.SpotEntity
import com.travelmeet.app.databinding.FragmentMySpotsBinding
import com.travelmeet.app.ui.feed.SpotAdapter
import com.travelmeet.app.ui.viewmodel.AuthViewModel
import com.travelmeet.app.ui.viewmodel.SpotViewModel

class MySpotsFragment : Fragment() {

companion object {
private const val PAGE_SIZE = 5
}

private var _binding: FragmentMySpotsBinding? = null
private val binding get() = _binding!!
private val authViewModel: AuthViewModel by activityViewModels()
private val spotViewModel: SpotViewModel by activityViewModels()
private lateinit var spotAdapter: SpotAdapter
private lateinit var spotsLayoutManager: LinearLayoutManager
private var pagedSpots: List<SpotEntity> = emptyList()
private var currentPage = 0

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -46,19 +55,81 @@ class MySpotsFragment : Fragment() {
spotViewModel.toggleLike(spot.id)
}
)
spotsLayoutManager = LinearLayoutManager(requireContext())
binding.rvMySpots.apply {
adapter = spotAdapter
layoutManager = LinearLayoutManager(requireContext())
layoutManager = spotsLayoutManager
}
setupPaginationControls()
}

private fun setupPaginationControls() {
binding.btnNextPage.setOnClickListener {
if (canGoNext()) {
currentPage++
submitMySpotsPage()
binding.rvMySpots.scrollToPosition(0)
}
}
binding.btnPrevPage.setOnClickListener {
if (currentPage > 0) {
currentPage--
submitMySpotsPage()
binding.rvMySpots.scrollToPosition(0)
}
}
}

private fun canGoNext(): Boolean {
val pages = totalPages()
return pages > 0 && currentPage < pages - 1
}

private fun submitMySpotsPage() {
val pages = totalPages()
if (pages == 0) {
spotAdapter.submitList(emptyList())
updatePaginationUi(pages)
return
}
if (currentPage >= pages) currentPage = pages - 1
val start = currentPage * PAGE_SIZE
val end = minOf(start + PAGE_SIZE, pagedSpots.size)
val newSpots = pagedSpots.subList(start, end)
spotAdapter.submitList(ArrayList(newSpots))
updatePaginationUi(pages)
}

private fun totalPages(): Int =
if (pagedSpots.isEmpty()) 0 else ((pagedSpots.size - 1) / PAGE_SIZE) + 1

private fun updatePaginationUi(pages: Int) {
val showPagination = pagedSpots.size > PAGE_SIZE
binding.paginationContainer.visibility = if (showPagination) View.VISIBLE else View.GONE
binding.btnPrevPage.isEnabled = showPagination && currentPage > 0
binding.btnNextPage.isEnabled = showPagination && currentPage < pages - 1
binding.tvPageIndicator.text = if (pages == 0) {
getString(R.string.page_indicator, 0, 0)
} else {
getString(R.string.page_indicator, currentPage + 1, pages)
}
}

private fun observeMySpots() {
val userId = authViewModel.currentUserId
if (userId != null) {
spotViewModel.getSpotsByUser(userId).observe(viewLifecycleOwner) { spots ->
spotAdapter.submitList(spots)
binding.emptyState.visibility = if (spots.isEmpty()) View.VISIBLE else View.GONE
binding.rvMySpots.visibility = if (spots.isEmpty()) View.GONE else View.VISIBLE
pagedSpots = spots
currentPage = 0
val isEmpty = spots.isEmpty()
binding.emptyState.visibility = if (isEmpty) View.VISIBLE else View.GONE
binding.rvMySpots.visibility = if (isEmpty) View.GONE else View.VISIBLE
if (isEmpty) {
spotAdapter.submitList(emptyList())
updatePaginationUi(0)
} else {
submitMySpotsPage()
}
}
}
}
Expand Down
44 changes: 43 additions & 1 deletion app/src/main/res/layout/fragment_feed.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:layout_marginBottom="72dp">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_spots"
Expand Down Expand Up @@ -55,4 +56,45 @@
android:textSize="16sp"
android:visibility="gone" />

<LinearLayout
android:id="@+id/pagination_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@color/background"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="16dp"
android:visibility="gone">

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_prev_page"
style="@style/TravelMeet.Button.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous_page"
android:textColor="@color/primary"
android:enabled="false" />

<TextView
android:id="@+id/tv_page_indicator"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/text_primary"
android:textSize="14sp"
android:text="@string/page_indicator" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_next_page"
style="@style/TravelMeet.Button.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_page"
android:enabled="false" />
</LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
46 changes: 45 additions & 1 deletion app/src/main/res/layout/fragment_my_spots.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
android:id="@+id/rv_my_spots"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="@+id/pagination_container"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
Expand All @@ -29,4 +29,48 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<LinearLayout
android:id="@+id/pagination_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:background="@color/surface"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="12dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_prev_page"
style="@style/TravelMeet.Button.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous_page"
android:textColor="@color/primary"
android:enabled="false" />

<TextView
android:id="@+id/tv_page_indicator"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_weight="1"
android:gravity="center"
android:textColor="@color/text_primary"
android:textSize="14sp"
android:text="@string/page_indicator" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_next_page"
style="@style/TravelMeet.Button.Primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next_page"
android:enabled="false" />
</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@
<string name="change_photo">Change Photo</string>
<string name="updating_profile">Updating profile…</string>
<string name="total_likes">Total likes: %d</string>
<string name="previous_page">Previous</string>
<string name="next_page">Next</string>
<string name="page_indicator">Page %1$d of %2$d</string>
<string name="page_indicator_default">Page 0 of 0</string>

<!-- Map -->
<string name="map">Map</string>
Expand Down