mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-03 02:47:34 +01:00
feat(posts): add possibility to reply to posts and comments (#1)
This commit is contained in:
parent
376f84cfef
commit
b371950d7b
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.CommunityInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
@ -73,3 +74,11 @@ actual fun getUserCommentsViewModel(user: UserModel): UserCommentsViewModel {
|
||||
)
|
||||
return res
|
||||
}
|
||||
|
||||
actual fun getCreateCommentViewModel(postId: Int, parentId: Int?): CreateCommentViewModel {
|
||||
val res: CreateCommentViewModel by inject(
|
||||
clazz = CreateCommentViewModel::class.java,
|
||||
parameters = { parametersOf(postId, parentId) }
|
||||
)
|
||||
return res
|
||||
}
|
@ -67,6 +67,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.Comm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Dropdown
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCommunityDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomSheet
|
||||
@ -470,6 +471,17 @@ class CommunityDetailScreen(
|
||||
)
|
||||
}
|
||||
},
|
||||
onReply = {
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
originalPost = post,
|
||||
onCommentCreated = {
|
||||
bottomSheetNavigator.hide()
|
||||
model.reduce(CommunityDetailMviModel.Intent.Refresh)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -60,6 +60,7 @@ fun PostCardFooter(
|
||||
Text(
|
||||
modifier = Modifier.padding(end = Spacing.s),
|
||||
text = "$comments",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
if (date != null) {
|
||||
@ -98,6 +99,7 @@ fun PostCardFooter(
|
||||
}
|
||||
}
|
||||
},
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
@ -149,6 +151,7 @@ fun PostCardFooter(
|
||||
)
|
||||
Text(
|
||||
text = "$score",
|
||||
style = MaterialTheme.typography.labelSmall,
|
||||
)
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
|
@ -0,0 +1,23 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
|
||||
interface CreateCommentMviModel :
|
||||
MviModel<CreateCommentMviModel.Intent, CreateCommentMviModel.UiState, CreateCommentMviModel.Effect> {
|
||||
|
||||
sealed interface Intent {
|
||||
data class SetText(val value: String) : Intent
|
||||
|
||||
object Send : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val text: String = "",
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
object Success : Effect
|
||||
|
||||
data class Failure(val message: String?) : Effect
|
||||
}
|
||||
}
|
@ -0,0 +1,167 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
||||
class CreateCommentScreen(
|
||||
private val originalPost: PostModel,
|
||||
private val originalComment: CommentModel? = null,
|
||||
private val onCommentCreated: () -> Unit = {},
|
||||
) : Screen {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val model = rememberScreenModel {
|
||||
getCreateCommentViewModel(postId = originalPost.id, parentId = originalComment?.id)
|
||||
}
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
is CreateCommentMviModel.Effect.Failure -> {
|
||||
snackbarHostState.showSnackbar(it.message ?: genericError)
|
||||
}
|
||||
|
||||
CreateCommentMviModel.Effect.Success -> onCommentCreated()
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.width(60.dp)
|
||||
.height(1.dp)
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = RoundedCornerShape(1.dp),
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = stringResource(MR.strings.create_comment_title),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
},
|
||||
snackbarHost = {
|
||||
SnackbarHost(snackbarHostState)
|
||||
}
|
||||
) { padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier = Modifier.padding(padding)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
LaunchedEffect(Unit) {
|
||||
scrollState.scrollTo(scrollState.maxValue)
|
||||
}
|
||||
|
||||
if (originalComment != null) {
|
||||
CommentCard(comment = originalComment)
|
||||
} else if (originalPost != null) {
|
||||
PostCard(
|
||||
post = originalPost,
|
||||
blurNsfw = false
|
||||
)
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.height(1.dp)
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
shape = RoundedCornerShape(1.dp),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
TextField(
|
||||
modifier = Modifier.height(300.dp).fillMaxWidth(),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_comment_body))
|
||||
},
|
||||
value = uiState.text,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Ascii,
|
||||
autoCorrect = false,
|
||||
imeAction = ImeAction.Done,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(CreateCommentMviModel.Intent.SetText(value))
|
||||
},
|
||||
)
|
||||
|
||||
Row {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
IconButton(
|
||||
content = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Send,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
onClick = {
|
||||
model.reduce(CreateCommentMviModel.Intent.Send)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommentRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class CreateCommentViewModel(
|
||||
private val postId: Int,
|
||||
private val parentId: Int?,
|
||||
private val mvi: DefaultMviModel<CreateCommentMviModel.Intent, CreateCommentMviModel.UiState, CreateCommentMviModel.Effect> = DefaultMviModel(
|
||||
CreateCommentMviModel.UiState()
|
||||
),
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val commentRepository: CommentRepository,
|
||||
) : ScreenModel,
|
||||
MviModel<CreateCommentMviModel.Intent, CreateCommentMviModel.UiState, CreateCommentMviModel.Effect> by mvi {
|
||||
|
||||
override fun reduce(intent: CreateCommentMviModel.Intent) {
|
||||
when (intent) {
|
||||
is CreateCommentMviModel.Intent.SetText -> {
|
||||
mvi.updateState {
|
||||
it.copy(text = intent.value)
|
||||
}
|
||||
}
|
||||
|
||||
CreateCommentMviModel.Intent.Send -> submit()
|
||||
}
|
||||
}
|
||||
|
||||
private fun submit() {
|
||||
mvi.scope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
val text = uiState.value.text
|
||||
commentRepository.create(
|
||||
postId = postId,
|
||||
parentId = parentId,
|
||||
text = text,
|
||||
auth = auth,
|
||||
)
|
||||
mvi.emitEffect(CreateCommentMviModel.Effect.Success)
|
||||
} catch (e: Throwable) {
|
||||
val message = e.message
|
||||
mvi.emitEffect(CreateCommentMviModel.Effect.Failure(message))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.Comm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.CommunityInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailMviModel
|
||||
@ -84,4 +85,12 @@ val commonUiModule = module {
|
||||
identityRepository = get(),
|
||||
)
|
||||
}
|
||||
factory { params ->
|
||||
CreateCommentViewModel(
|
||||
postId = params[0],
|
||||
parentId = params[1],
|
||||
identityRepository = get(),
|
||||
commentRepository = get(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.CommunityInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
@ -39,3 +40,8 @@ expect fun getUserCommentsViewModel(
|
||||
expect fun getInstanceInfoViewModel(
|
||||
url: String,
|
||||
): InstanceInfoViewModel
|
||||
|
||||
expect fun getCreateCommentViewModel(
|
||||
postId: Int,
|
||||
parentId: Int? = null,
|
||||
): CreateCommentViewModel
|
@ -48,6 +48,7 @@ fun CommentCard(
|
||||
saved = comment.saved,
|
||||
upVoted = comment.myVote > 0,
|
||||
downVoted = comment.myVote < 0,
|
||||
comments = comment.comments,
|
||||
onUpVote = onUpVote,
|
||||
onDownVote = onDownVote,
|
||||
onSave = onSave,
|
||||
|
@ -56,6 +56,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardSubtitle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardTitle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getPostDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
@ -300,6 +301,18 @@ class PostDetailScreen(
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = {
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
originalPost = post,
|
||||
originalComment = comment,
|
||||
onCommentCreated = {
|
||||
bottomSheetNavigator.hide()
|
||||
model.reduce(PostDetailMviModel.Intent.Refresh)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -36,6 +36,7 @@ import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import com.github.diegoberaldin.racconforlemmy.core.utils.toLocalPixel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
@ -43,10 +44,12 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserCounters
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getUserCommentsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
@ -69,6 +72,7 @@ internal class UserDetailCommentsScreen(
|
||||
) { getUserCommentsViewModel(user) }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
|
||||
LaunchedEffect(parentModel) {
|
||||
parentModel.uiState.map { it.sortType }.distinctUntilChanged().onEach { sortType ->
|
||||
@ -207,6 +211,18 @@ internal class UserDetailCommentsScreen(
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = {
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
originalPost = PostModel(id = comment.postId),
|
||||
originalComment = comment,
|
||||
onCommentCreated = {
|
||||
bottomSheetNavigator.hide()
|
||||
model.reduce(UserCommentsMviModel.Intent.Refresh)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -37,6 +37,7 @@ import androidx.compose.ui.unit.dp
|
||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.LocalBottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import com.github.diegoberaldin.racconforlemmy.core.utils.toLocalPixel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
@ -47,6 +48,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserCounters
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getUserPostsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailSection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
@ -77,6 +79,7 @@ internal class UserDetailPostsScreen(
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val navigator = LocalNavigator.currentOrThrow
|
||||
val bottomSheetNavigator = LocalBottomSheetNavigator.current
|
||||
|
||||
LaunchedEffect(parentModel) {
|
||||
parentModel.uiState.map { it.sortType }.distinctUntilChanged().onEach { sortType ->
|
||||
@ -228,6 +231,17 @@ internal class UserDetailPostsScreen(
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = {
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
originalPost = post,
|
||||
onCommentCreated = {
|
||||
bottomSheetNavigator.hide()
|
||||
model.reduce(UserPostsMviModel.Intent.Refresh)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.di
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.CommunityInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.instanceinfo.InstanceInfoViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
@ -15,30 +16,33 @@ import org.koin.core.component.inject
|
||||
import org.koin.core.parameter.parametersOf
|
||||
|
||||
actual fun getPostDetailViewModel(post: PostModel): PostDetailViewModel =
|
||||
PostDetailScreenViewModelHelper.getPostDetailModel(post)
|
||||
CommonUiViewModelHelper.getPostDetailModel(post)
|
||||
|
||||
actual fun getCommunityDetailViewModel(
|
||||
community: CommunityModel,
|
||||
otherInstance: String,
|
||||
): CommunityDetailViewModel =
|
||||
PostDetailScreenViewModelHelper.getCommunityDetailModel(community, otherInstance)
|
||||
CommonUiViewModelHelper.getCommunityDetailModel(community, otherInstance)
|
||||
|
||||
actual fun getCommunityInfoViewModel(community: CommunityModel): CommunityInfoViewModel =
|
||||
PostDetailScreenViewModelHelper.getCommunityInfoModel(community)
|
||||
CommonUiViewModelHelper.getCommunityInfoModel(community)
|
||||
|
||||
actual fun getInstanceInfoViewModel(url: String): InstanceInfoViewModel =
|
||||
PostDetailScreenViewModelHelper.getInstanceInfoModel(url)
|
||||
CommonUiViewModelHelper.getInstanceInfoModel(url)
|
||||
|
||||
actual fun getUserDetailViewModel(user: UserModel): UserDetailViewModel =
|
||||
PostDetailScreenViewModelHelper.getUserDetailModel(user)
|
||||
CommonUiViewModelHelper.getUserDetailModel(user)
|
||||
|
||||
actual fun getUserPostsViewModel(user: UserModel): UserPostsViewModel =
|
||||
PostDetailScreenViewModelHelper.getUserPostsModel(user)
|
||||
CommonUiViewModelHelper.getUserPostsModel(user)
|
||||
|
||||
actual fun getUserCommentsViewModel(user: UserModel): UserCommentsViewModel =
|
||||
PostDetailScreenViewModelHelper.getUserCommentsModel(user)
|
||||
CommonUiViewModelHelper.getUserCommentsModel(user)
|
||||
|
||||
object PostDetailScreenViewModelHelper : KoinComponent {
|
||||
actual fun getCreateCommentViewModel(postId: Int, parentId: Int?): CreateCommentViewModel =
|
||||
CommonUiViewModelHelper.getCreateCommentModel(postId, parentId)
|
||||
|
||||
object CommonUiViewModelHelper : KoinComponent {
|
||||
|
||||
fun getPostDetailModel(post: PostModel): PostDetailViewModel {
|
||||
val model: PostDetailViewModel by inject(
|
||||
@ -91,4 +95,11 @@ object PostDetailScreenViewModelHelper : KoinComponent {
|
||||
)
|
||||
return model
|
||||
}
|
||||
|
||||
fun getCreateCommentModel(postId: Int, parentId: Int?): CreateCommentViewModel {
|
||||
val model: CreateCommentViewModel by inject(
|
||||
parameters = { parametersOf(postId, parentId) }
|
||||
)
|
||||
return model
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data
|
||||
|
||||
data class CommentModel(
|
||||
val id: Int = 0,
|
||||
val postId: Int = 0,
|
||||
val text: String,
|
||||
val community: CommunityModel? = null,
|
||||
val creator: UserModel? = null,
|
||||
@ -9,4 +10,5 @@ data class CommentModel(
|
||||
val myVote: Int = 0,
|
||||
val saved: Boolean = false,
|
||||
val publishDate: String? = null,
|
||||
val comments: Int? = null,
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CreateCommentForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CreateCommentLikeForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.SaveCommentForm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.provider.ServiceProvider
|
||||
@ -85,4 +86,19 @@ class CommentRepository(
|
||||
)
|
||||
services.comment.save(data)
|
||||
}
|
||||
|
||||
suspend fun create(
|
||||
postId: Int,
|
||||
parentId: Int?,
|
||||
text: String,
|
||||
auth: String,
|
||||
) {
|
||||
val data = CreateCommentForm(
|
||||
content = text,
|
||||
postId = postId,
|
||||
parentId = parentId,
|
||||
auth = auth,
|
||||
)
|
||||
services.comment.create(data)
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommentReplyView
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommentSortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommentView
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.Community
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.CommunityFollowerView
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.All
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Local
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.api.dto.ListingType.Subscribed
|
||||
@ -103,6 +102,8 @@ internal fun CommentView.toModel() = CommentModel(
|
||||
saved = saved,
|
||||
myVote = myVote ?: 0,
|
||||
publishDate = comment.published,
|
||||
postId = comment.postId,
|
||||
comments = counts.childCount,
|
||||
)
|
||||
|
||||
internal fun Community.toModel() = CommunityModel(
|
||||
@ -127,6 +128,7 @@ internal fun PersonMentionView.toModel() = PersonMentionModel(
|
||||
),
|
||||
comment = CommentModel(
|
||||
id = comment.id,
|
||||
postId = comment.postId,
|
||||
text = comment.content,
|
||||
community = community.toModel(),
|
||||
),
|
||||
@ -150,6 +152,7 @@ internal fun CommentReplyView.toModel() = PersonMentionModel(
|
||||
),
|
||||
comment = CommentModel(
|
||||
id = comment.id,
|
||||
postId = comment.postId,
|
||||
text = comment.content,
|
||||
community = community.toModel(),
|
||||
publishDate = comment.published,
|
||||
|
@ -44,6 +44,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.ListingTypeBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailScreen
|
||||
@ -223,6 +224,17 @@ class PostListScreen : Screen {
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = {
|
||||
bottomSheetNavigator.show(
|
||||
CreateCommentScreen(
|
||||
originalPost = post,
|
||||
onCommentCreated = {
|
||||
bottomSheetNavigator.hide()
|
||||
model.reduce(PostListMviModel.Intent.Refresh)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -68,13 +68,14 @@ class LoginBottomSheet(
|
||||
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
is LoginBottomSheetMviModel.Effect.LoginError -> {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = it.message,
|
||||
message = it.message ?: genericError,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ interface LoginBottomSheetMviModel :
|
||||
)
|
||||
|
||||
sealed interface Effect {
|
||||
data class LoginError(val message: String) : Effect
|
||||
data class LoginError(val message: String?) : Effect
|
||||
object LoginSuccess : Effect
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class LoginBottomSheetViewModel(
|
||||
|
||||
if (result.isFailure) {
|
||||
result.exceptionOrNull()?.also {
|
||||
val message = it.message ?: "Generic error"
|
||||
val message = it.message
|
||||
mvi.emitEffect(LoginBottomSheetMviModel.Effect.LoginError(message))
|
||||
}
|
||||
} else {
|
||||
|
@ -100,4 +100,7 @@
|
||||
<string name="inbox_item_reply_post">replied to your post in</string>
|
||||
<string name="inbox_item_reply_comment">replied to your comment in</string>
|
||||
<string name="inbox_item_mention">mentioned you in</string>
|
||||
|
||||
<string name="create_comment_title">New comment</string>
|
||||
<string name="create_comment_body">Comment body</string>
|
||||
</resources>
|
@ -94,7 +94,10 @@
|
||||
<string name="inbox_listing_type_title">Tipo inbox</string>
|
||||
<string name="inbox_listing_type_all">Tutti</string>
|
||||
<string name="inbox_listing_type_unread">Non letti</string>
|
||||
<string name="inbox_item_reply_post">replied to your post in</string>
|
||||
<string name="inbox_item_reply_comment">replied to your comment in</string>
|
||||
<string name="inbox_item_mention">mentioned you in</string>
|
||||
<string name="inbox_item_reply_post">ha risposto al tuo post su</string>
|
||||
<string name="inbox_item_reply_comment">ha risposto al tuo commento tu</string>
|
||||
<string name="inbox_item_mention">ti ha menzionato in</string>
|
||||
|
||||
<string name="create_comment_title">Nuovo commento</string>
|
||||
<string name="create_comment_body">Contenuto commento</string>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user