Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature : joining a team #143

Merged
merged 17 commits into from
Jan 23, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.bizilabs.streeek.lib.data.repositories.TeamInvitationRepositoryImpl
import com.bizilabs.streeek.lib.data.repositories.TeamRepositoryImpl
import com.bizilabs.streeek.lib.data.repositories.UserRepositoryImpl
import com.bizilabs.streeek.lib.data.repositories.VersionRepositoryImpl
import com.bizilabs.streeek.lib.data.repositories.team.TeamRequestRepositoryImpl
import com.bizilabs.streeek.lib.domain.repositories.AccountRepository
import com.bizilabs.streeek.lib.domain.repositories.AuthenticationRepository
import com.bizilabs.streeek.lib.domain.repositories.ContributionRepository
Expand All @@ -27,6 +28,7 @@ import com.bizilabs.streeek.lib.domain.repositories.TeamInvitationRepository
import com.bizilabs.streeek.lib.domain.repositories.TeamRepository
import com.bizilabs.streeek.lib.domain.repositories.UserRepository
import com.bizilabs.streeek.lib.domain.repositories.VersionRepository
import com.bizilabs.streeek.lib.domain.repositories.team.TeamRequestRepository
import com.bizilabs.streeek.lib.local.LocalModule
import com.bizilabs.streeek.lib.remote.RemoteModule
import org.koin.core.qualifier.named
Expand Down Expand Up @@ -94,4 +96,10 @@ val dataModule =
)
}
single<PointsRepository> { PointsRepository() }
single<TeamRequestRepository> {
TeamRequestRepositoryImpl(
remoteSource = get(),
accountLocalSource = get(),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.bizilabs.streeek.lib.data.mappers.team

import com.bizilabs.streeek.lib.data.mappers.toDomain
import com.bizilabs.streeek.lib.domain.models.TeamAndMembersDomain
import com.bizilabs.streeek.lib.remote.models.supabase.TeamAndMembersDTO

fun TeamAndMembersDTO.toDomain() =
TeamAndMembersDomain(
team = team.toDomain(),
members = members?.map { it.toDomain() } ?: emptyList(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.bizilabs.streeek.lib.data.mappers.team

import com.bizilabs.streeek.lib.data.mappers.toDomain
import com.bizilabs.streeek.lib.domain.models.team.MemberAccountRequestDomain
import com.bizilabs.streeek.lib.domain.models.team.TeamAccountJoinRequestDomain
import com.bizilabs.streeek.lib.domain.models.team.TeamJoinRequestDomain
import com.bizilabs.streeek.lib.remote.models.supabase.team.MemberAccountRequestDTO
import com.bizilabs.streeek.lib.remote.models.supabase.team.TeamAccountJoinRequestDTO
import com.bizilabs.streeek.lib.remote.models.supabase.team.TeamJoinRequestDTO

fun TeamJoinRequestDTO.toDomain() =
TeamJoinRequestDomain(
id = id,
status = status,
createdAt = createdAt,
)

fun TeamJoinRequestDomain.toDTO() =
TeamJoinRequestDTO(
id = id,
status = status,
createdAt = createdAt,
)

fun MemberAccountRequestDTO.toDomain() =
MemberAccountRequestDomain(
request = request.toDomain(),
team = team.toDomain(),
members = members?.map { it.toDomain() } ?: emptyList(),
)

fun TeamAccountJoinRequestDTO.toDomain() =
TeamAccountJoinRequestDomain(
request = request.toDomain(),
account = account.toDomain(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.bizilabs.streeek.lib.data.paging

import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.bizilabs.streeek.lib.data.paging.PagingHelpers.START_PAGE
import com.bizilabs.streeek.lib.remote.helpers.NetworkResult

fun <T : Any, R : Any> genericPager(
getResults: suspend (Int) -> NetworkResult<T>,
mapper: (T) -> List<R>,
) = Pager(
config = PagingConfig(pageSize = PagingHelpers.PAGE_SIZE, enablePlaceholders = false),
pagingSourceFactory = {
GenericPagingSource(
getResults = getResults,
mapper = mapper,
)
},
).flow

private class GenericPagingSource<T : Any, R : Any>(
private val getResults: suspend (Int) -> NetworkResult<T>,
private val mapper: (T) -> List<R>,
) : PagingSource<Int, R>() {
override fun getRefreshKey(state: PagingState<Int, R>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, R> {
val page = params.key ?: START_PAGE
val result = getResults(page)
if (result is NetworkResult.Failure) return LoadResult.Error(result.exception)
val data = (result as NetworkResult.Success).data
val list = mapper(data)
val nextKey =
when {
list.isEmpty() || list.size < PagingHelpers.PAGE_SIZE -> null
else -> page.plus(1)
}

val previousKey = if (page == START_PAGE) null else page.minus(1)
return LoadResult.Page(data = list, prevKey = previousKey, nextKey = nextKey)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.bizilabs.streeek.lib.data.paging

import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState
import com.bizilabs.streeek.lib.data.mappers.toCache
import com.bizilabs.streeek.lib.data.mappers.toDomain
import com.bizilabs.streeek.lib.data.paging.PagingHelpers.START_PAGE
import com.bizilabs.streeek.lib.domain.models.TeamDetailsDomain
import com.bizilabs.streeek.lib.domain.models.TeamMemberDomain
import com.bizilabs.streeek.lib.domain.models.updateOrCreate
import com.bizilabs.streeek.lib.local.sources.account.AccountLocalSource
import com.bizilabs.streeek.lib.local.sources.team.TeamLocalSource
import com.bizilabs.streeek.lib.remote.helpers.NetworkResult
import com.bizilabs.streeek.lib.remote.helpers.PAGE_SIZE
import com.bizilabs.streeek.lib.remote.sources.team.TeamRemoteSource
import kotlinx.coroutines.flow.firstOrNull
import timber.log.Timber

class TeamMembersPagingSource(
private val team: TeamDetailsDomain,
private val teamLocalSource: TeamLocalSource,
private val teamRemoteSource: TeamRemoteSource,
private val accountLocalSource: AccountLocalSource,
) : PagingSource<Int, TeamMemberDomain>() {
override fun getRefreshKey(state: PagingState<Int, TeamMemberDomain>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TeamMemberDomain> {
val page = params.key ?: PagingHelpers.START_PAGE

val accountId =
accountLocalSource.account.firstOrNull()?.id
?: return LoadResult.Error(Exception("Couldn't get logged in account"))

if (page == team.page) {
val prev = if (page == START_PAGE) null else page.minus(1)
val next = if (team.members.size < PAGE_SIZE) null else page + 1
return LoadResult.Page(data = team.members.filterNot { member -> member.rank <= 3 }, prevKey = prev, nextKey = next)
}

val result =
teamRemoteSource.fetchTeam(teamId = team.team.id, accountId = accountId, page = page)

if (result is NetworkResult.Failure) return LoadResult.Error(result.exception)

val data = (result as NetworkResult.Success).data.toDomain()
val cache = team.updateOrCreate(page = page, team = data).toCache()
if (page == START_PAGE) teamLocalSource.update(cache)

val list = data.members.filterNot { member -> member.rank <= 3 }

val nextKey =
when {
list.isEmpty() || list.size < PagingHelpers.PAGE_SIZE -> null
else -> page.plus(1)
}

Timber.d(
"Members -> \n${
buildString {
append("Page : $page\n")
append("Members : $list")
}
}",
)

val previousKey = if (page == START_PAGE) null else page.minus(1)

return LoadResult.Page(data = list, prevKey = previousKey, nextKey = nextKey)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,56 +4,42 @@ import androidx.paging.PagingSource
import androidx.paging.PagingSource.LoadParams
import androidx.paging.PagingSource.LoadResult
import androidx.paging.PagingState
import com.bizilabs.streeek.lib.data.mappers.toCache
import com.bizilabs.streeek.lib.data.mappers.team.toDomain
import com.bizilabs.streeek.lib.data.mappers.toDomain
import com.bizilabs.streeek.lib.data.paging.PagingHelpers.START_PAGE
import com.bizilabs.streeek.lib.domain.models.TeamDetailsDomain
import com.bizilabs.streeek.lib.domain.models.TeamMemberDomain
import com.bizilabs.streeek.lib.domain.models.updateOrCreate
import com.bizilabs.streeek.lib.domain.models.TeamAndMembersDomain
import com.bizilabs.streeek.lib.local.sources.account.AccountLocalSource
import com.bizilabs.streeek.lib.local.sources.team.TeamLocalSource
import com.bizilabs.streeek.lib.remote.helpers.NetworkResult
import com.bizilabs.streeek.lib.remote.helpers.PAGE_SIZE
import com.bizilabs.streeek.lib.remote.sources.team.TeamRemoteSource
import kotlinx.coroutines.flow.firstOrNull
import timber.log.Timber

class TeamsPagingSource(
private val team: TeamDetailsDomain,
private val teamLocalSource: TeamLocalSource,
private val teamRemoteSource: TeamRemoteSource,
private val accountLocalSource: AccountLocalSource,
) : PagingSource<Int, TeamMemberDomain>() {
override fun getRefreshKey(state: PagingState<Int, TeamMemberDomain>): Int? {
) : PagingSource<Int, TeamAndMembersDomain>() {
override fun getRefreshKey(state: PagingState<Int, TeamAndMembersDomain>): Int? {
return state.anchorPosition?.let { anchorPosition ->
state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1)
?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1)
}
}

override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TeamMemberDomain> {
val page = params.key ?: PagingHelpers.START_PAGE
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, TeamAndMembersDomain> {
val page = params.key ?: START_PAGE

val accountId =
accountLocalSource.account.firstOrNull()?.id
?: return LoadResult.Error(Exception("Couldn't get logged in account"))

if (page == team.page) {
val prev = if (page == START_PAGE) null else page.minus(1)
val next = if (team.members.size < PAGE_SIZE) null else page + 1
return LoadResult.Page(data = team.members.filterNot { member -> member.rank <= 3 }, prevKey = prev, nextKey = next)
}

val result =
teamRemoteSource.fetchTeam(teamId = team.team.id, accountId = accountId, page = page)
val result = teamRemoteSource.fetchTeamAndMembers(accountId = accountId, page = page)

if (result is NetworkResult.Failure) return LoadResult.Error(result.exception)

val data = (result as NetworkResult.Success).data.toDomain()
val cache = team.updateOrCreate(page = page, team = data).toCache()
if (page == START_PAGE) teamLocalSource.update(cache)
val data = (result as NetworkResult.Success).data

val list = data.members.filterNot { member -> member.rank <= 3 }
val list = data.map { it.toDomain() }

val nextKey =
when {
Expand All @@ -62,10 +48,10 @@ class TeamsPagingSource(
}

Timber.d(
"Members -> \n${
"Teams Data -> \n${
buildString {
append("Page : $page\n")
append("Members : $list")
append("Teams : $list")
}
}",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import com.bizilabs.streeek.lib.data.mappers.team.toDomain
import com.bizilabs.streeek.lib.data.mappers.toCache
import com.bizilabs.streeek.lib.data.mappers.toDomain
import com.bizilabs.streeek.lib.data.paging.PagingHelpers
import com.bizilabs.streeek.lib.data.paging.TeamMembersPagingSource
import com.bizilabs.streeek.lib.data.paging.TeamsPagingSource
import com.bizilabs.streeek.lib.domain.helpers.DataResult
import com.bizilabs.streeek.lib.domain.models.TeamAndMembersDomain
import com.bizilabs.streeek.lib.domain.models.TeamDetailsDomain
import com.bizilabs.streeek.lib.domain.models.TeamMemberDomain
import com.bizilabs.streeek.lib.domain.models.TeamWithDetailDomain
Expand Down Expand Up @@ -48,7 +50,7 @@ class TeamRepositoryImpl(
return Pager(
config = PagingConfig(pageSize = PagingHelpers.PAGE_SIZE, enablePlaceholders = false),
pagingSourceFactory = {
TeamsPagingSource(
TeamMembersPagingSource(
team = team,
accountLocalSource = accountLocalSource,
teamLocalSource = localSource,
Expand Down Expand Up @@ -90,6 +92,18 @@ class TeamRepositoryImpl(
.asDataResult { list -> list.map { it.toDomain() } }
}

override fun getTeamsAndMembers(): Flow<PagingData<TeamAndMembersDomain>> {
return Pager(
config = PagingConfig(pageSize = PagingHelpers.PAGE_SIZE, enablePlaceholders = false),
pagingSourceFactory = {
TeamsPagingSource(
accountLocalSource = accountLocalSource,
teamRemoteSource = remoteSource,
)
},
).flow
}

override suspend fun getTeam(
id: Long,
page: Int,
Expand Down
Loading
Loading