Skip to content

Commit

Permalink
add pagination to history screen (#37)
Browse files Browse the repository at this point in the history
* feat: add pagination to HistoryScreen

* refactor: update PullToRefresh

* fix warnings
  • Loading branch information
dead8309 authored Apr 30, 2024
1 parent 9ef5ebb commit 4d6c10d
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 229 deletions.
4 changes: 2 additions & 2 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions .idea/other.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.paging.compose.collectAsLazyPagingItems
import `in`.iot.lab.teacherreview.feature_teacherlist.ui.navigation.TeacherListNavGraph
import `in`.iot.lab.teacherreview.feature_teacherlist.ui.screen.HistoryScreenControl
import `in`.iot.lab.teacherreview.feature_teacherlist.ui.screen.ProfileScreen
Expand Down Expand Up @@ -47,9 +48,11 @@ fun HomeNavGraph(
// History Bottom Navigation Option
composable(
BottomNavRoutes.HistoryRoute.route,
content = { HistoryScreenControl(
content = {
val lazyPagingItems = historyVm.historyScreenPagingFlow.collectAsLazyPagingItems()
HistoryScreenControl(
historyActions = historyVm::historyAction,
getHistoryApiCallState = historyVm.getHistoryApiCallState,
lazyPagingItems = lazyPagingItems,
currentUserId = currentUserId
) }
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package `in`.iot.lab.teacherreview.feature_teacherlist.data.paging_source

import androidx.paging.PagingSource
import androidx.paging.PagingState
import `in`.iot.lab.teacherreview.core.utils.Constants
import `in`.iot.lab.teacherreview.feature_authentication.domain.repository.AuthRepository
import `in`.iot.lab.teacherreview.feature_teacherlist.data.remote.ReviewsApi
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.IndividualReviewData

class ReviewHistorySource (
private val studentId: String,
private val authRepository: AuthRepository,
private val reviewsApi: ReviewsApi
) : PagingSource<Int, IndividualReviewData>() {
override fun getRefreshKey(state: PagingState<Int, IndividualReviewData>): Int? {
return state.anchorPosition
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, IndividualReviewData> {
return try {
val page = params.key ?: 0
val skip = page * Constants.ITEMS_PER_PAGE

val response = reviewsApi.getStudentReviewHistory(
token = authRepository.getUserIdToken().getOrDefault(""),
studentId = studentId,
limitValue = Constants.ITEMS_PER_PAGE,
skip = skip
)

val data = response.body()!!.individualReviewData ?: emptyList()

LoadResult.Page(
data = data,
prevKey = if (page == 0) null else page - 1,
nextKey = if (data.isEmpty()) null else page + 1
)
} catch (e: Exception) {
LoadResult.Error(e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ interface ReviewsApi {
): Response<ReviewData>


@GET("reviews?${"$"}populate=faculty&${"$"}populate=createdBy")
@GET("reviews?${"$"}populate=faculty&${"$"}populate=createdBy&${"$"}sort[createdAt]=-1")
suspend fun getStudentReviewHistory(
@Header("Authorization") token: String,
@Query("createdBy") studentId: String,
@Query("${"$"}limit") limitValue: Int
@Query("${"$"}limit") limitValue: Int,
@Query("${"$"}skip") skip: Int = 0
): Response<ReviewData>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingData
import `in`.iot.lab.teacherreview.core.utils.Constants
import `in`.iot.lab.teacherreview.feature_authentication.domain.repository.AuthRepository
import `in`.iot.lab.teacherreview.feature_teacherlist.data.paging_source.ReviewHistorySource
import `in`.iot.lab.teacherreview.feature_teacherlist.data.paging_source.ReviewsSource
import `in`.iot.lab.teacherreview.feature_teacherlist.data.remote.ReviewsApi
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.IndividualReviewData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.ReviewData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.ReviewPostData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.repository.ReviewRepository
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -64,29 +64,23 @@ class ReviewRepositoryImpl @Inject constructor(
}

override suspend fun getStudentsReviewHistory(
studentId: String,
limitValue: Int
): Result<ReviewData> {
studentId: String
): Result<Flow<PagingData<IndividualReviewData>>> {
try {
val response = reviewsApi.getStudentReviewHistory(
studentId = studentId,
limitValue = limitValue,
token = getToken()
)
Log.d(TAG, response.toString())
if (!response.isSuccessful) {
throw Exception("Error Connecting to the Server")
}

// TODO: Maybe cache the response here
var reviewData = response.body()!!

val sortByDesc = reviewData.individualReviewData?.sortedByDescending {
it.createdAt
}
reviewData = reviewData.copy(individualReviewData = sortByDesc)
val pager = Pager(
config = PagingConfig(
pageSize = Constants.ITEMS_PER_PAGE,
prefetchDistance = Constants.PREFETCH_DISTANCE,
)
) {
ReviewHistorySource(
studentId = studentId,
authRepository = authRepository,
reviewsApi = reviewsApi
)
}.flow

return Result.success(reviewData)
return Result.success(pager)
} catch (e: Exception) {
e.printStackTrace()
return Result.failure(e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,18 @@ data class RatingData(
val markingRating: RatingParameterData? = null,
@SerializedName("attendance")
val attendanceRating: RatingParameterData? = null
)
) {
/**
* This function calculates the Average Rating
*
* @return Double This returns the Average Rating
*/
fun calculateAverageRating(): Double {
return with(this) {
attendanceRating?.ratedPoints
?.plus(teachingRating?.ratedPoints!!)
?.plus(markingRating?.ratedPoints!!)
?.plus(overallRating)?.div(4) ?: 0.0
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ package `in`.iot.lab.teacherreview.feature_teacherlist.domain.repository

import androidx.paging.PagingData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.IndividualReviewData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.ReviewData
import `in`.iot.lab.teacherreview.feature_teacherlist.domain.models.remote.ReviewPostData
import kotlinx.coroutines.flow.Flow

interface ReviewRepository {
suspend fun postReview(review: ReviewPostData): Result<ReviewPostData>
suspend fun getTeacherReviews(facultyId: String): Result<Flow<PagingData<IndividualReviewData>>>
suspend fun getStudentsReviewHistory(studentId: String, limitValue: Int): Result<ReviewData>
suspend fun getStudentsReviewHistory(
studentId: String
): Result<Flow<PagingData<IndividualReviewData>>>

// TODO: To be added in the next release (maybe ?)
// suspend fun deleteReview(reviewId: String): Result<Boolean>
Expand Down
Loading

0 comments on commit 4d6c10d

Please sign in to comment.