feat(community): allow to view post for foreign communities

This commit is contained in:
Diego Beraldin 2023-08-15 17:41:25 +02:00
parent 029ce48669
commit 4df6156f30
10 changed files with 117 additions and 47 deletions

View File

@ -21,10 +21,13 @@ actual fun getPostDetailViewModel(post: PostModel): PostDetailViewModel {
return res
}
actual fun getCommunityDetailViewModel(community: CommunityModel): CommunityDetailViewModel {
actual fun getCommunityDetailViewModel(
community: CommunityModel,
otherInstance: String,
): CommunityDetailViewModel {
val res: CommunityDetailViewModel by inject(
clazz = CommunityDetailViewModel::class.java,
parameters = { parametersOf(community) },
parameters = { parametersOf(community, otherInstance) },
)
return res
}

View File

@ -85,18 +85,23 @@ import io.kamel.image.asyncPainterResource
class CommunityDetailScreen(
private val community: CommunityModel,
private val otherInstance: String = "",
private val onBack: () -> Unit,
) : Screen {
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterialApi::class)
@Composable
override fun Content() {
val model = rememberScreenModel(community.id.toString()) {
getCommunityDetailViewModel(community)
val model = rememberScreenModel(community.id.toString() + otherInstance) {
getCommunityDetailViewModel(
community = community,
otherInstance = otherInstance,
)
}
model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState()
val navigator = LocalNavigator.currentOrThrow
val bottomSheetNavigator = LocalBottomSheetNavigator.current
val isOnOtherInstance = otherInstance.isNotEmpty()
Scaffold(
modifier = Modifier.background(MaterialTheme.colorScheme.surface).padding(Spacing.xs),
@ -376,10 +381,14 @@ class CommunityDetailScreen(
}
SwipeToDismiss(
state = dismissState,
directions = setOf(
DismissDirection.StartToEnd,
DismissDirection.EndToStart,
),
directions = if (isOnOtherInstance) {
emptySet()
} else {
setOf(
DismissDirection.StartToEnd,
DismissDirection.EndToStart,
)
},
dismissThresholds = {
FractionalThreshold(threshold)
},
@ -467,29 +476,41 @@ class CommunityDetailScreen(
)
},
post = post,
onUpVote = {
model.reduce(
CommunityDetailMviModel.Intent.UpVotePost(
post = post,
feedback = true,
),
)
onUpVote = if (isOnOtherInstance) {
null
} else {
{
model.reduce(
CommunityDetailMviModel.Intent.UpVotePost(
post = post,
feedback = true,
),
)
}
},
onDownVote = {
model.reduce(
CommunityDetailMviModel.Intent.DownVotePost(
post = post,
feedback = true,
),
)
onDownVote = if (isOnOtherInstance) {
null
} else {
{
model.reduce(
CommunityDetailMviModel.Intent.DownVotePost(
post = post,
feedback = true,
),
)
}
},
onSave = {
model.reduce(
CommunityDetailMviModel.Intent.SavePost(
post = post,
feedback = true,
),
)
onSave = if (isOnOtherInstance) {
null
} else {
{
model.reduce(
CommunityDetailMviModel.Intent.SavePost(
post = post,
feedback = true,
),
)
}
},
)
}

View File

@ -21,6 +21,7 @@ import kotlinx.coroutines.launch
class CommunityDetailViewModel(
private val mvi: DefaultMviModel<CommunityDetailMviModel.Intent, CommunityDetailMviModel.UiState, CommunityDetailMviModel.Effect>,
private val community: CommunityModel,
private val otherInstance: String,
private val identityRepository: IdentityRepository,
private val communityRepository: CommunityRepository,
private val postsRepository: PostsRepository,
@ -104,19 +105,28 @@ class CommunityDetailViewModel(
val auth = identityRepository.authToken.value
val refreshing = currentState.refreshing
val sort = currentState.sortType
val commentList = postsRepository.getAll(
auth = auth,
communityId = community.id,
page = currentPage,
sort = sort,
)
val itemList = if (otherInstance.isNotEmpty()) {
postsRepository.getAllInInstance(
instance = otherInstance,
communityId = community.id,
page = currentPage,
sort = sort,
)
} else {
postsRepository.getAll(
auth = auth,
communityId = community.id,
page = currentPage,
sort = sort,
)
}
currentPage++
val canFetchMore = commentList.size >= CommentRepository.DEFAULT_PAGE_SIZE
val canFetchMore = itemList.size >= CommentRepository.DEFAULT_PAGE_SIZE
mvi.updateState {
val newItems = if (refreshing) {
commentList
itemList
} else {
it.posts + commentList
it.posts + itemList
}
it.copy(
posts = newItems,

View File

@ -34,6 +34,7 @@ val commonUiModule = module {
CommunityDetailViewModel(
mvi = DefaultMviModel(CommunityDetailMviModel.UiState()),
community = params[0],
otherInstance = params[1],
identityRepository = get(),
communityRepository = get(),
postsRepository = get(),

View File

@ -17,6 +17,7 @@ expect fun getPostDetailViewModel(
expect fun getCommunityDetailViewModel(
community: CommunityModel,
otherInstance: String = "",
): CommunityDetailViewModel
expect fun getCommunityInfoViewModel(

View File

@ -58,6 +58,7 @@ class InstanceInfoScreen(
model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState()
val navigator = LocalNavigator.currentOrThrow
val instanceName = url.replace("https://", "")
Scaffold(
modifier = Modifier.background(MaterialTheme.colorScheme.surface).padding(Spacing.xs),
@ -74,7 +75,6 @@ class InstanceInfoScreen(
)
},
title = {
val instanceName = url.replace("https://", "")
Text(
text = stringResource(MR.strings.instance_detail_title, instanceName),
style = MaterialTheme.typography.bodyLarge,
@ -130,6 +130,7 @@ class InstanceInfoScreen(
navigator.push(
CommunityDetailScreen(
community = it,
otherInstance = instanceName,
onBack = {
navigator.pop()
},

View File

@ -65,18 +65,19 @@ class InstanceInfoViewModel(
mvi.updateState { it.copy(loading = true) }
val auth = identityRepository.authToken.value
val refreshing = currentState.refreshing
val instance = url.replace("https://", "")
val itemList = communityRepository.getAllInInstance(
auth = auth,
instance = url.replace("https://", ""),
instance = instance,
page = currentPage,
)
currentPage++
val canFetchMore = itemList.size >= CommentRepository.DEFAULT_PAGE_SIZE
mvi.updateState {
val newItems = if (refreshing) {
itemList
itemList.filter { e -> e.instanceUrl == url }
} else {
it.communities + itemList
it.communities + itemList.filter { e -> e.instanceUrl == url }
}
it.copy(
communities = newItems,

View File

@ -17,8 +17,11 @@ import org.koin.core.parameter.parametersOf
actual fun getPostDetailViewModel(post: PostModel): PostDetailViewModel =
PostDetailScreenViewModelHelper.getPostDetailModel(post)
actual fun getCommunityDetailViewModel(community: CommunityModel): CommunityDetailViewModel =
PostDetailScreenViewModelHelper.getCommunityDetailModel(community)
actual fun getCommunityDetailViewModel(
community: CommunityModel,
otherInstance: String,
): CommunityDetailViewModel =
PostDetailScreenViewModelHelper.getCommunityDetailModel(community, otherInstance)
actual fun getCommunityInfoViewModel(community: CommunityModel): CommunityInfoViewModel =
PostDetailScreenViewModelHelper.getCommunityInfoModel(community)
@ -44,9 +47,12 @@ object PostDetailScreenViewModelHelper : KoinComponent {
return model
}
fun getCommunityDetailModel(community: CommunityModel): CommunityDetailViewModel {
fun getCommunityDetailModel(
community: CommunityModel,
otherInstance: String,
): CommunityDetailViewModel {
val model: CommunityDetailViewModel by inject(
parameters = { parametersOf(community) },
parameters = { parametersOf(community, otherInstance) },
)
return model
}

View File

@ -11,6 +11,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.utils.to
class PostsRepository(
private val services: ServiceProvider,
private val customServices: ServiceProvider,
) {
companion object {
@ -37,6 +38,26 @@ class PostsRepository(
return dto.map { it.toModel() }
}
suspend fun getAllInInstance(
instance: String = "",
page: Int,
limit: Int = DEFAULT_PAGE_SIZE,
type: ListingType = ListingType.Local,
sort: SortType = SortType.Active,
communityId: Int? = null,
): List<PostModel> {
customServices.changeInstance(instance)
val response = customServices.post.getAll(
communityId = communityId,
page = page,
limit = limit,
type = type.toDto(),
sort = sort.toDto(),
)
val dto = response.body()?.posts ?: emptyList()
return dto.map { it.toModel() }
}
fun asUpVoted(post: PostModel, voted: Boolean) = post.copy(
myVote = if (voted) 1 else 0,
score = when {

View File

@ -10,7 +10,12 @@ import org.koin.core.qualifier.named
import org.koin.dsl.module
val repositoryModule = module {
singleOf(::PostsRepository)
single {
PostsRepository(
services = get(),
customServices = get(named("custom")),
)
}
single {
CommunityRepository(
services = get(),