Skip to content
Merged
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
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ dependencies {
implementation(Libraries.Compressor.ZELORY_COMPRESSOR)
implementation(Libraries.Shimmer.SHIMMER)
implementation(Libraries.Splash.SPLASH_SCREEN)
implementation(Libraries.Paging.PAGING3)

implementation(platform(Libraries.Firebase.FIREBASE))
implementation(Libraries.Firebase.ANALYTICS)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
package com.fitmate.fitmate.data.repository

import com.fitmate.fitmate.data.model.dto.FitGroupFilter
import androidx.paging.Pager
import androidx.paging.PagingConfig
import com.fitmate.fitmate.data.model.dto.FitMateRequest
import com.fitmate.fitmate.data.model.dto.GetFitGroupDetail
import com.fitmate.fitmate.data.model.dto.GetFitMateList
import com.fitmate.fitmate.data.model.dto.RegisterResponse
import com.fitmate.fitmate.data.source.CategoryPagingSource
import com.fitmate.fitmate.data.source.remote.GroupService
import com.fitmate.fitmate.domain.repository.GroupRepository
import retrofit2.Response

class GroupRepositoryImpl(private val groupService: GroupService) : GroupRepository {
override suspend fun fitGroupFilter(withMaxGroup: Boolean, category: Int, pageNumber: Int, pageSize: Int): FitGroupFilter {
return groupService.fitGroupFilter(withMaxGroup, category, pageNumber, pageSize)
}
override suspend fun fitGroupFilter(withMaxGroup: Boolean, category: Int, pageNumber: Int, pageSize: Int) = Pager(
config = PagingConfig(
pageSize,
enablePlaceholders = true
),
pagingSourceFactory = {
CategoryPagingSource(groupService,category,pageSize)
}
).flow

override suspend fun fitGroupAll(withMaxGroup: Boolean, pageSize: Int): FitGroupFilter {
return groupService.fitGroupAll(withMaxGroup, pageSize)
}
override suspend fun fitGroupAll(withMaxGroup: Boolean, pageNumber: Int ,pageSize: Int) = Pager(
config = PagingConfig(
pageSize,
enablePlaceholders = true
),
pagingSourceFactory = {
CategoryPagingSource(groupService, 0, pageSize)
}
).flow

override suspend fun getFitGroupDetail(fitGroupId: Int): GetFitGroupDetail {
return groupService.getFitGroupDetail(fitGroupId)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.fitmate.fitmate.data.source

import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.fitmate.fitmate.data.model.dto.FitGroupDetail
import com.fitmate.fitmate.data.source.remote.GroupService

class CategoryPagingSource(
private val groupService: GroupService,
private val categoryNum: Int,
private val pageSize: Int
): PagingSource<Int, FitGroupDetail>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, FitGroupDetail> {
return try {
val page = params.key ?: 0
val response = if (categoryNum == 0){
groupService.fitGroupAll(false, page ,pageSize)
}else{
groupService.fitGroupFilter(true, categoryNum, page, pageSize)
}
val prevKey = if (response.first) null else page - 1
val nextKey = if (response.last) null else page + 1

LoadResult.Page(
data = response.content,
prevKey = prevKey,
nextKey = nextKey
)
}catch (e: Exception) {
LoadResult.Error(e)
}
}

override fun getRefreshKey(state: PagingState<Int, FitGroupDetail>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ interface GroupService {
@GET("/fit-group-service/groups/filters")
suspend fun fitGroupAll(
@Query("withMaxGroup") withMaxGroup: Boolean,
@Query("pageNumber") pageNumber: Int,
@Query("pageSize") pageSize: Int
): FitGroupFilter

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.fitmate.fitmate.domain.repository

import androidx.paging.PagingData
import com.fitmate.fitmate.data.model.dto.FitGroupDetail
import com.fitmate.fitmate.data.model.dto.FitGroupFilter
import com.fitmate.fitmate.data.model.dto.GetFitGroupDetail
import com.fitmate.fitmate.data.model.dto.GetFitMateList
import com.fitmate.fitmate.data.model.dto.RegisterResponse
import kotlinx.coroutines.flow.Flow
import retrofit2.Response

interface GroupRepository {
suspend fun fitGroupFilter(withMaxGroup: Boolean, category: Int, pageNumber: Int, pageSize: Int): FitGroupFilter
suspend fun fitGroupFilter(withMaxGroup: Boolean, category: Int, pageNumber: Int, pageSize: Int): Flow<PagingData<FitGroupDetail>>

suspend fun fitGroupAll(withMaxGroup: Boolean, pageSize: Int): FitGroupFilter
suspend fun fitGroupAll(withMaxGroup: Boolean, pageNumber: Int ,pageSize: Int): Flow<PagingData<FitGroupDetail>>

suspend fun getFitGroupDetail(fitGroupId: Int): GetFitGroupDetail

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.fitmate.fitmate.domain.usecase

import androidx.paging.PagingData
import com.fitmate.fitmate.data.model.dto.FitGroupDetail
import com.fitmate.fitmate.data.model.dto.FitGroupFilter
import com.fitmate.fitmate.data.model.dto.GetFitGroupDetail
import com.fitmate.fitmate.data.model.dto.GetFitMateList
import com.fitmate.fitmate.data.model.dto.RegisterResponse
import com.fitmate.fitmate.domain.repository.GroupRepository
import kotlinx.coroutines.flow.Flow
import retrofit2.Response
import javax.inject.Inject

class GroupUseCase @Inject constructor(private val groupRepository: GroupRepository) {

suspend fun fitGroupFilter(withMaxGroup: Boolean, category: Int, pageNumber: Int, pageSize: Int)
: FitGroupFilter = groupRepository.fitGroupFilter(withMaxGroup, category, pageNumber, pageSize)
: Flow<PagingData<FitGroupDetail>> = groupRepository.fitGroupFilter(withMaxGroup, category, pageNumber, pageSize)

suspend fun fitGroupAll(withMaxGroup: Boolean, pageSize: Int): FitGroupFilter = groupRepository.fitGroupAll(withMaxGroup, pageSize)
suspend fun fitGroupAll(withMaxGroup: Boolean, pageNumber: Int, pageSize: Int): Flow<PagingData<FitGroupDetail>> = groupRepository.fitGroupAll(withMaxGroup, pageNumber, pageSize)

suspend fun getFitGroupDetail(fitGroupId: Int): GetFitGroupDetail = groupRepository.getFitGroupDetail(fitGroupId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import android.util.Log
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.fitmate.fitmate.MainActivity
import com.fitmate.fitmate.R
Expand All @@ -14,6 +14,7 @@ import com.fitmate.fitmate.presentation.ui.category.list.adapter.CategoryAdapter
import com.fitmate.fitmate.presentation.viewmodel.GroupViewModel
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

@AndroidEntryPoint
Expand All @@ -38,25 +39,30 @@ class CategoryFragment: Fragment(R.layout.fragment_category) {
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume() activated")
getAllFitGroups()
//getAllFitGroups()
viewModel.getGroups(true, 0, 0)
}

private fun initView(view: View) {
binding = FragmentCategoryBinding.bind(view)
binding.recyclerViewCategory.layoutManager = LinearLayoutManager(context)
binding.recyclerViewCategory.adapter = CategoryAdapter(this) {}

startShimmer()
}

private fun observeModel() {
startShimmer()
viewModel.run {
categoryItems.observe(viewLifecycleOwner) { categoryItems ->
lifecycleScope.launch {
stopShimmer()
(binding.recyclerViewCategory.adapter as CategoryAdapter).submitList(categoryItems.toList())
viewModelScope.launch {
pagingData.collectLatest {
if (it != null){
stopShimmer()
(binding.recyclerViewCategory.adapter as CategoryAdapter).submitData(lifecycle, it)
}
}
}


errorMessage.observe(viewLifecycleOwner) { errorMessage ->
if(errorMessage != null) {
Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_LONG).show()
Expand All @@ -74,18 +80,19 @@ class CategoryFragment: Fragment(R.layout.fragment_category) {
binding.chipGroupCategory.setOnCheckedStateChangeListener { _, checkedIds ->
if (checkedIds.isEmpty()) {
Log.d(TAG, "connect in 0")
viewModel.getGroups(true, null, null, 1000)
viewModel.getGroups(true, 0, 0)
} else {
val categoryId = chipToCategoryMap[checkedIds[0]] ?: return@setOnCheckedStateChangeListener
Log.d(TAG, "connect in $categoryId")
viewModel.getGroups(true, categoryId, 0, 1000)
viewModel.getGroups(true, categoryId, 0)
}
}
}


private fun getAllFitGroups() {
binding.chipGroupCategory.clearCheck()
viewModel.getGroups(true, null, null, 1000)
viewModel.getGroups(true, 0, 1000)
}

private fun startShimmer() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package com.fitmate.fitmate.presentation.ui.category.list.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import com.fitmate.fitmate.databinding.ItemCategoryBinding
import com.fitmate.fitmate.domain.model.CategoryItem
import com.fitmate.fitmate.presentation.ui.category.list.CategoryViewHolder

class CategoryAdapter(private val fragment: Fragment, private val onClick: (CategoryItem) -> Unit): ListAdapter<CategoryItem, CategoryViewHolder>(
class CategoryAdapter(private val fragment: Fragment, private val onClick: (CategoryItem) -> Unit): PagingDataAdapter<CategoryItem, CategoryViewHolder>(
CategoryItemDiffCallback
) {

Expand All @@ -20,7 +21,7 @@ class CategoryAdapter(private val fragment: Fragment, private val onClick: (Cate

override fun onBindViewHolder(holder: CategoryViewHolder, position: Int) {
val item = getItem(position)
holder.bind(item)
if (item != null) holder.bind(item)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
package com.fitmate.fitmate.presentation.viewmodel

import android.util.Log
import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.PagingData
import androidx.paging.cachedIn
import androidx.paging.map
import com.fitmate.fitmate.data.model.dto.FitGroup
import com.fitmate.fitmate.data.model.dto.FitGroupFilter
import com.fitmate.fitmate.data.model.dto.GetFitGroupDetail
import com.fitmate.fitmate.data.model.dto.GetFitMateList
import com.fitmate.fitmate.data.model.dto.RegisterResponse
import com.fitmate.fitmate.domain.model.CategoryItem
import com.fitmate.fitmate.domain.usecase.DBChatUseCase
import com.fitmate.fitmate.domain.usecase.GroupUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import retrofit2.Response
import javax.inject.Inject

@HiltViewModel
Expand Down Expand Up @@ -57,32 +56,31 @@ class GroupViewModel @Inject constructor(
private val _successMessage = MutableLiveData<String?>()
val successMessage: LiveData<String?> = _successMessage

private val _pagingData = MutableStateFlow<PagingData<CategoryItem>?>(null)
val pagingData: StateFlow<PagingData<CategoryItem>?> = _pagingData

fun getGroups(withMaxGroup: Boolean, category: Int? = null, pageNumber: Int? = null, pageSize: Int? = null) {

fun getGroups(withMaxGroup: Boolean, category: Int, pageNumber: Int = 0, pageSize: Int = 8) {
viewModelScope.launch {
_isLoading.value = true
try {
val response = if (category != null && pageNumber != null) {
groupUseCase.fitGroupFilter(withMaxGroup, category, pageNumber, pageSize!!)
} else {
groupUseCase.fitGroupAll(withMaxGroup, pageSize!!)
}

val categoryItems = response.content.map {
CategoryItem(
title = it.fitGroupName,
fitCount = "${it.frequency}회 / 1주",
peopleCount = "${it.presentFitMateCount} / ${it.maxFitMate}",
comment = it.introduction,
fitGroupId = it.fitGroupId,
thumbnail = try {
it.multiMediaEndPoints[0]
} catch (e: Exception) {
"null"
}
)
groupUseCase.fitGroupFilter(withMaxGroup, category, pageNumber, pageSize)
.cachedIn(this).collectLatest { list ->
_pagingData.value = list.map {
CategoryItem(
title = it.fitGroupName,
fitCount = "${it.frequency}회 / 1주",
peopleCount = "${it.presentFitMateCount} / ${it.maxFitMate}",
comment = it.introduction,
fitGroupId = it.fitGroupId,
thumbnail = try {
it.multiMediaEndPoints[0]
} catch (e: Exception) {
"null"
}
)
}
}
_categoryItems.value = categoryItems
_isLoading.value = false
} catch (e: Exception) {
Log.d(TAG, "There is NO DATA in Server. $e")
Expand All @@ -92,7 +90,7 @@ class GroupViewModel @Inject constructor(
}
}

fun getFitGroupDetail(fitGroupId: Int){
fun getFitGroupDetail(fitGroupId: Int) {
viewModelScope.launch {
_isLoading.value = true
try {
Expand Down
4 changes: 4 additions & 0 deletions buildSrc/src/main/kotlin/Libraries.kt
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,8 @@ object Libraries {
const val SPLASH_SCREEN = "androidx.core:core-splashscreen:${Versions.SPLASH}"
}

object Paging {
const val PAGING3 = "androidx.paging:paging-runtime:${Versions.PAGING}"
}

}
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ object Versions {
const val SHIMMER = "0.5.0"
const val OKHTTP = "4.12.0"
const val SPLASH = "1.0.1"
const val PAGING = "3.1.0"
}