mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 11:38:40 +01:00
feat: cross-post (#117)
* feat: cross-post * refactor: id-based options * fix: show actions only for logged users
This commit is contained in:
parent
a4971ac670
commit
5d032fd583
@ -20,6 +20,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation.Navigat
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateReportMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems.SavedItemsMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
@ -108,9 +109,9 @@ actual fun getCreateCommentViewModel(
|
||||
return res
|
||||
}
|
||||
|
||||
actual fun getCreatePostViewModel(communityId: Int?, editedPostId: Int?): CreatePostMviModel {
|
||||
actual fun getCreatePostViewModel(editedPostId: Int?): CreatePostMviModel {
|
||||
val res: CreatePostMviModel by inject(clazz = CreatePostMviModel::class.java,
|
||||
parameters = { parametersOf(communityId, editedPostId) })
|
||||
parameters = { parametersOf(editedPostId) })
|
||||
return res
|
||||
}
|
||||
|
||||
@ -151,6 +152,11 @@ actual fun getCreateReportViewModel(
|
||||
return res
|
||||
}
|
||||
|
||||
actual fun getSelectCommunityViewModel(): SelectCommunityMviModel {
|
||||
val res: SelectCommunityMviModel by inject(SelectCommunityMviModel::class.java)
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
actual fun getCustomTextToolbar(
|
||||
|
@ -72,6 +72,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communityInfo.Comm
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
|
||||
@ -321,16 +323,18 @@ class CommunityDetailScreen(
|
||||
}
|
||||
},
|
||||
)
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(CommunityDetailMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
}
|
||||
},
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(CommunityDetailMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
if (!isOnOtherInstance) {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.Create,
|
||||
@ -378,21 +382,36 @@ class CommunityDetailScreen(
|
||||
community = uiState.community,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
options = listOf(
|
||||
stringResource(MR.strings.community_detail_info),
|
||||
stringResource(MR.strings.community_detail_instance_info),
|
||||
stringResource(MR.strings.community_detail_block),
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
Option(
|
||||
OptionId.Info,
|
||||
stringResource(MR.strings.community_detail_info)
|
||||
),
|
||||
Option(
|
||||
OptionId.InfoInstance,
|
||||
stringResource(MR.strings.community_detail_instance_info)
|
||||
),
|
||||
Option(
|
||||
OptionId.Block,
|
||||
stringResource(MR.strings.community_detail_block)
|
||||
),
|
||||
Option(
|
||||
OptionId.BlockInstance,
|
||||
stringResource(MR.strings.community_detail_block_instance)
|
||||
),
|
||||
),
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
3 -> model.reduce(CommunityDetailMviModel.Intent.BlockInstance)
|
||||
2 -> model.reduce(CommunityDetailMviModel.Intent.Block)
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.BlockInstance -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.BlockInstance
|
||||
)
|
||||
|
||||
1 -> {
|
||||
OptionId.Block -> model.reduce(CommunityDetailMviModel.Intent.Block)
|
||||
|
||||
OptionId.InfoInstance -> {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
InstanceInfoScreen(
|
||||
url = uiState.community.instanceUrl,
|
||||
@ -400,11 +419,13 @@ class CommunityDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.Info -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CommunityInfoScreen(uiState.community),
|
||||
)
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -544,54 +565,95 @@ class CommunityDetailScreen(
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_hide))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
if (post.creator?.id == uiState.currentUserId && !isOnOtherInstance) {
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionIdx ->
|
||||
when (optionIdx) {
|
||||
5 -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.DeletePost(
|
||||
post.id
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Hide,
|
||||
stringResource(MR.strings.post_action_hide)
|
||||
)
|
||||
)
|
||||
}
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.CrossPost,
|
||||
stringResource(MR.strings.post_action_cross_post)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
if (post.creator?.id == uiState.currentUserId && !isOnOtherInstance) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Delete -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.DeletePost(post.id)
|
||||
)
|
||||
|
||||
4 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
)
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
1 -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.Hide(
|
||||
post.id
|
||||
)
|
||||
OptionId.Hide -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.Hide(post.id)
|
||||
)
|
||||
|
||||
else -> model.reduce(
|
||||
OptionId.Share -> model.reduce(
|
||||
CommunityDetailMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -31,13 +31,13 @@ fun CollapsedCommentCard(
|
||||
modifier: Modifier = Modifier,
|
||||
separateUpAndDownVotes: Boolean = false,
|
||||
autoLoadImages: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
onDownVote: (() -> Unit)? = null,
|
||||
onSave: (() -> Unit)? = null,
|
||||
onReply: (() -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onToggleExpanded: (() -> Unit)? = null,
|
||||
) {
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
|
@ -40,7 +40,7 @@ fun CommentCard(
|
||||
hideCommunity: Boolean = true,
|
||||
hideIndent: Boolean = false,
|
||||
autoLoadImages: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onClick: (() -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
onDownVote: (() -> Unit)? = null,
|
||||
@ -48,7 +48,7 @@ fun CommentCard(
|
||||
onReply: (() -> Unit)? = null,
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onToggleExpanded: (() -> Unit)? = null,
|
||||
) {
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
|
@ -51,8 +51,8 @@ fun CommunityHeader(
|
||||
community: CommunityModel,
|
||||
modifier: Modifier = Modifier,
|
||||
autoLoadImages: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
options: List<Option> = emptyList(),
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onOpenImage: ((String) -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
@ -114,7 +114,7 @@ fun CommunityHeader(
|
||||
// y = (-50).dp,
|
||||
),
|
||||
) {
|
||||
options.forEachIndexed { idx, option ->
|
||||
options.forEach { option ->
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = Spacing.m,
|
||||
@ -122,10 +122,10 @@ fun CommunityHeader(
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(idx)
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
),
|
||||
text = option,
|
||||
text = option.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
|
||||
@ -28,7 +28,7 @@ fun CommunityItem(
|
||||
val communityName = community.name
|
||||
val communityIcon = community.icon.orEmpty()
|
||||
val communityHost = community.host
|
||||
val iconSize = if (small) 24.dp else 30.dp
|
||||
val iconSize = if (small) IconSize.m else IconSize.l
|
||||
Row(
|
||||
modifier = modifier.padding(
|
||||
vertical = Spacing.xs,
|
||||
@ -62,6 +62,7 @@ fun CommunityItem(
|
||||
append(title)
|
||||
},
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Text(
|
||||
text = buildString {
|
||||
|
@ -13,7 +13,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.MultiCommunityModel
|
||||
|
||||
@ -26,7 +26,7 @@ fun MultiCommunityItem(
|
||||
) {
|
||||
val title = community.name
|
||||
val communityIcon = community.icon.orEmpty()
|
||||
val iconSize = if (small) 24.dp else 30.dp
|
||||
val iconSize = if (small) IconSize.m else IconSize.l
|
||||
Row(
|
||||
modifier = modifier.padding(
|
||||
vertical = Spacing.xs,
|
||||
|
@ -0,0 +1,20 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
data class Option(
|
||||
val id: OptionId,
|
||||
val text: String,
|
||||
)
|
||||
|
||||
sealed class OptionId(val value: Int) {
|
||||
data object Share : OptionId(0)
|
||||
data object Hide : OptionId(1)
|
||||
data object SeeRaw : OptionId(2)
|
||||
data object CrossPost : OptionId(3)
|
||||
data object Report : OptionId(4)
|
||||
data object Edit : OptionId(5)
|
||||
data object Delete : OptionId(6)
|
||||
data object Info : OptionId(7)
|
||||
data object InfoInstance : OptionId(8)
|
||||
data object Block : OptionId(9)
|
||||
data object BlockInstance : OptionId(10)
|
||||
}
|
@ -53,7 +53,7 @@ fun PostCard(
|
||||
fullHeightImage: Boolean = true,
|
||||
limitBodyHeight: Boolean = false,
|
||||
blurNsfw: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
@ -61,7 +61,7 @@ fun PostCard(
|
||||
onSave: (() -> Unit)? = null,
|
||||
onReply: (() -> Unit)? = null,
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
@ -132,7 +132,7 @@ private fun CompactPost(
|
||||
hideAuthor: Boolean,
|
||||
blurNsfw: Boolean,
|
||||
separateUpAndDownVotes: Boolean,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
@ -140,7 +140,7 @@ private fun CompactPost(
|
||||
onSave: (() -> Unit)? = null,
|
||||
onReply: (() -> Unit)? = null,
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Column(
|
||||
@ -215,7 +215,7 @@ private fun ExtendedPost(
|
||||
fullHeightImage: Boolean = true,
|
||||
roundedCornerImage: Boolean = true,
|
||||
backgroundColor: Color = MaterialTheme.colorScheme.background,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
@ -223,7 +223,7 @@ private fun ExtendedPost(
|
||||
onSave: (() -> Unit)? = null,
|
||||
onReply: (() -> Unit)? = null,
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Column(
|
||||
|
@ -54,12 +54,12 @@ fun PostCardFooter(
|
||||
saved: Boolean = false,
|
||||
upVoted: Boolean = false,
|
||||
downVoted: Boolean = false,
|
||||
options: List<String> = emptyList(),
|
||||
options: List<Option> = emptyList(),
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
onDownVote: (() -> Unit)? = null,
|
||||
onSave: (() -> Unit)? = null,
|
||||
onReply: (() -> Unit)? = null,
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
) {
|
||||
var optionsExpanded by remember { mutableStateOf(false) }
|
||||
var optionsOffset by remember { mutableStateOf(Offset.Zero) }
|
||||
@ -232,7 +232,7 @@ fun PostCardFooter(
|
||||
y = optionsOffset.y.toLocalDp(),
|
||||
),
|
||||
) {
|
||||
options.forEachIndexed { idx, text ->
|
||||
options.forEach { option ->
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = Spacing.m,
|
||||
@ -240,10 +240,10 @@ fun PostCardFooter(
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(idx)
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
),
|
||||
text = text,
|
||||
text = option.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ fun UserHeader(
|
||||
user: UserModel,
|
||||
modifier: Modifier = Modifier,
|
||||
autoLoadImages: Boolean = true,
|
||||
options: List<String> = emptyList(),
|
||||
onOptionSelected: ((Int) -> Unit)? = null,
|
||||
options: List<Option> = emptyList(),
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onOpenImage: ((String) -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
@ -117,7 +117,7 @@ fun UserHeader(
|
||||
y = optionsOffset.y.toLocalDp(),
|
||||
),
|
||||
) {
|
||||
options.forEachIndexed { idx, option ->
|
||||
options.forEach { option ->
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = Spacing.m,
|
||||
@ -125,10 +125,10 @@ fun UserHeader(
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(idx)
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
),
|
||||
text = option,
|
||||
text = option.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ 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.BottomSheetHandle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardBody
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
|
||||
@ -170,7 +172,12 @@ class CreateCommentScreen(
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = {
|
||||
rawContent = originalComment
|
||||
@ -192,7 +199,12 @@ class CreateCommentScreen(
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = {
|
||||
rawContent = originalPost
|
||||
|
@ -4,6 +4,7 @@ import androidx.compose.runtime.Stable
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import dev.icerock.moko.resources.desc.StringDesc
|
||||
|
||||
@Stable
|
||||
@ -12,6 +13,7 @@ interface CreatePostMviModel :
|
||||
ScreenModel {
|
||||
|
||||
sealed interface Intent {
|
||||
data class SetCommunity(val value: CommunityModel) : Intent
|
||||
data class SetTitle(val value: String) : Intent
|
||||
data class SetUrl(val value: String) : Intent
|
||||
data class ChangeNsfw(val value: Boolean) : Intent
|
||||
@ -54,6 +56,9 @@ interface CreatePostMviModel :
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val communityInfo: String = "",
|
||||
val communityId: Int? = null,
|
||||
val communityError: StringDesc? = null,
|
||||
val title: String = "",
|
||||
val titleError: StringDesc? = null,
|
||||
val bodyError: StringDesc? = null,
|
||||
|
@ -6,13 +6,13 @@ 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.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Groups
|
||||
import androidx.compose.material.icons.filled.Image
|
||||
import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
@ -28,6 +28,7 @@ import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -38,6 +39,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
@ -60,12 +62,16 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Section
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.TextFormattingBar
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getCreatePostViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityDialog
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.getGalleryHelper
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallbackArgs
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.shareUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.localized
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
@ -75,15 +81,13 @@ import kotlinx.coroutines.flow.onEach
|
||||
class CreatePostScreen(
|
||||
private val communityId: Int? = null,
|
||||
private val editedPost: PostModel? = null,
|
||||
private val crossPost: PostModel? = null,
|
||||
) : Screen {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val model = rememberScreenModel {
|
||||
getCreatePostViewModel(
|
||||
communityId = communityId,
|
||||
editedPostId = editedPost?.id,
|
||||
)
|
||||
getCreatePostViewModel(editedPostId = editedPost?.id)
|
||||
}
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
@ -91,17 +95,63 @@ class CreatePostScreen(
|
||||
val genericError = stringResource(MR.strings.message_generic_error)
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
val galleryHelper = remember { getGalleryHelper() }
|
||||
val crossPostText = stringResource(MR.strings.create_post_cross_post_text)
|
||||
var bodyTextFieldValue by remember {
|
||||
mutableStateOf(TextFieldValue(text = editedPost?.text.orEmpty()))
|
||||
val text = when {
|
||||
crossPost != null -> buildString {
|
||||
append(crossPostText)
|
||||
append(" ")
|
||||
append(crossPost.shareUrl)
|
||||
}
|
||||
|
||||
editedPost != null -> {
|
||||
editedPost.text
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
mutableStateOf(TextFieldValue(text = text))
|
||||
}
|
||||
val bodyFocusRequester = remember { FocusRequester() }
|
||||
val urlFocusRequester = remember { FocusRequester() }
|
||||
val focusManager = LocalFocusManager.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
var openImagePicker by remember { mutableStateOf(false) }
|
||||
var openImagePickerInBody by remember { mutableStateOf(false) }
|
||||
if (openImagePicker) {
|
||||
galleryHelper.getImageFromGallery { bytes ->
|
||||
openImagePicker = false
|
||||
model.reduce(CreatePostMviModel.Intent.ImageSelected(bytes))
|
||||
}
|
||||
}
|
||||
if (openImagePickerInBody) {
|
||||
galleryHelper.getImageFromGallery { bytes ->
|
||||
openImagePickerInBody = false
|
||||
model.reduce(CreatePostMviModel.Intent.InsertImageInBody(bytes))
|
||||
}
|
||||
}
|
||||
var openSelectCommunity by remember { mutableStateOf(false) }
|
||||
val keyboardScrollConnection = remember {
|
||||
object : NestedScrollConnection {
|
||||
override fun onPreScroll(
|
||||
available: Offset,
|
||||
source: NestedScrollSource,
|
||||
): Offset {
|
||||
focusManager.clearFocus()
|
||||
return Offset.Zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(model) {
|
||||
model.reduce(CreatePostMviModel.Intent.SetTitle(editedPost?.title.orEmpty()))
|
||||
model.reduce(CreatePostMviModel.Intent.SetUrl(editedPost?.url.orEmpty()))
|
||||
val referencePost = editedPost ?: crossPost
|
||||
model.reduce(CreatePostMviModel.Intent.SetTitle(referencePost?.title.orEmpty()))
|
||||
model.reduce(CreatePostMviModel.Intent.SetUrl(referencePost?.url.orEmpty()))
|
||||
if (communityId != null) {
|
||||
model.reduce(
|
||||
CreatePostMviModel.Intent.SetCommunity(CommunityModel(id = communityId))
|
||||
)
|
||||
}
|
||||
|
||||
model.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
@ -123,15 +173,26 @@ class CreatePostScreen(
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
val keyboardScrollConnection = remember {
|
||||
object : NestedScrollConnection {
|
||||
override fun onPreScroll(
|
||||
available: Offset,
|
||||
source: NestedScrollSource,
|
||||
): Offset {
|
||||
focusManager.clearFocus()
|
||||
return Offset.Zero
|
||||
}
|
||||
DisposableEffect(key) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as CommunityModel)?.also { community ->
|
||||
model.reduce(CreatePostMviModel.Intent.SetCommunity(community))
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.SelectCommunity
|
||||
)
|
||||
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
if (openSelectCommunity) {
|
||||
openSelectCommunity = false
|
||||
}
|
||||
}, key, NotificationCenterContractKeys.CloseDialog
|
||||
)
|
||||
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +208,10 @@ class CreatePostScreen(
|
||||
) {
|
||||
BottomSheetHandle()
|
||||
Text(
|
||||
text = stringResource(MR.strings.create_post_title),
|
||||
text = when {
|
||||
else ->
|
||||
stringResource(MR.strings.create_post_title)
|
||||
},
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
@ -164,8 +228,52 @@ class CreatePostScreen(
|
||||
.padding(padding)
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
// community
|
||||
if (crossPost != null) {
|
||||
TextField(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onFocusChanged(
|
||||
rememberCallbackArgs {
|
||||
if (it.hasFocus) {
|
||||
openSelectCommunity = true
|
||||
}
|
||||
},
|
||||
),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.create_post_community))
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Groups,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
textStyle = MaterialTheme.typography.bodyMedium,
|
||||
value = uiState.communityInfo,
|
||||
readOnly = true,
|
||||
singleLine = true,
|
||||
onValueChange = {},
|
||||
isError = uiState.communityError != null,
|
||||
supportingText = {
|
||||
if (uiState.communityError != null) {
|
||||
Text(
|
||||
text = uiState.communityError?.localized().orEmpty(),
|
||||
color = MaterialTheme.colorScheme.error,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// title
|
||||
TextField(
|
||||
modifier = Modifier.fillMaxWidth().heightIn(max = 300.dp),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
@ -199,21 +307,7 @@ class CreatePostScreen(
|
||||
},
|
||||
)
|
||||
|
||||
var openImagePicker by remember { mutableStateOf(false) }
|
||||
var openImagePickerInBody by remember { mutableStateOf(false) }
|
||||
if (openImagePicker) {
|
||||
galleryHelper.getImageFromGallery { bytes ->
|
||||
openImagePicker = false
|
||||
model.reduce(CreatePostMviModel.Intent.ImageSelected(bytes))
|
||||
}
|
||||
}
|
||||
if (openImagePickerInBody) {
|
||||
galleryHelper.getImageFromGallery { bytes ->
|
||||
openImagePickerInBody = false
|
||||
model.reduce(CreatePostMviModel.Intent.InsertImageInBody(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
// image
|
||||
TextField(
|
||||
modifier = Modifier.fillMaxWidth().focusRequester(urlFocusRequester),
|
||||
colors = TextFieldDefaults.colors(
|
||||
@ -262,6 +356,7 @@ class CreatePostScreen(
|
||||
},
|
||||
)
|
||||
|
||||
// NSFW
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(
|
||||
vertical = Spacing.s, horizontal = Spacing.m
|
||||
@ -377,5 +472,9 @@ class CreatePostScreen(
|
||||
if (uiState.loading) {
|
||||
ProgressHud()
|
||||
}
|
||||
|
||||
if (openSelectCommunity) {
|
||||
SelectCommunityDialog().Content()
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class CreatePostViewModel(
|
||||
private val communityId: Int?,
|
||||
private val editedPostId: Int?,
|
||||
private val mvi: DefaultMviModel<CreatePostMviModel.Intent, CreatePostMviModel.UiState, CreatePostMviModel.Effect>,
|
||||
private val identityRepository: IdentityRepository,
|
||||
@ -47,6 +46,20 @@ class CreatePostViewModel(
|
||||
|
||||
override fun reduce(intent: CreatePostMviModel.Intent) {
|
||||
when (intent) {
|
||||
is CreatePostMviModel.Intent.SetCommunity -> {
|
||||
val community = intent.value
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
communityId = community.id,
|
||||
communityInfo = buildString {
|
||||
append(community.name)
|
||||
append("@")
|
||||
append(community.host)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
is CreatePostMviModel.Intent.SetTitle -> {
|
||||
mvi.updateState {
|
||||
it.copy(title = intent.value)
|
||||
@ -132,6 +145,8 @@ class CreatePostViewModel(
|
||||
bodyError = null,
|
||||
)
|
||||
}
|
||||
|
||||
val communityId = uiState.value.communityId
|
||||
val title = uiState.value.title
|
||||
val url = uiState.value.url
|
||||
val nsfw = uiState.value.nsfw
|
||||
@ -160,6 +175,15 @@ class CreatePostViewModel(
|
||||
}
|
||||
valid = false
|
||||
}
|
||||
if (communityId == null) {
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
communityError = message_missing_field.desc(),
|
||||
)
|
||||
}
|
||||
valid = false
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
return
|
||||
}
|
||||
@ -169,9 +193,9 @@ class CreatePostViewModel(
|
||||
try {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
when {
|
||||
communityId != null -> {
|
||||
postRepository.create(
|
||||
communityId = communityId,
|
||||
editedPostId != null -> {
|
||||
postRepository.edit(
|
||||
postId = editedPostId,
|
||||
title = title,
|
||||
body = body,
|
||||
url = url,
|
||||
@ -180,9 +204,9 @@ class CreatePostViewModel(
|
||||
)
|
||||
}
|
||||
|
||||
editedPostId != null -> {
|
||||
postRepository.edit(
|
||||
postId = editedPostId,
|
||||
communityId != null -> {
|
||||
postRepository.create(
|
||||
communityId = communityId,
|
||||
title = title,
|
||||
body = body,
|
||||
url = url,
|
||||
|
@ -29,6 +29,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateRepor
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateReportViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems.SavedItemsMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems.SavedItemsViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.di.utilsModule
|
||||
@ -134,8 +136,7 @@ val commonUiModule = module {
|
||||
factory<CreatePostMviModel> { params ->
|
||||
CreatePostViewModel(
|
||||
mvi = DefaultMviModel(CreatePostMviModel.UiState()),
|
||||
communityId = params[0],
|
||||
editedPostId = params[1],
|
||||
editedPostId = params[0],
|
||||
identityRepository = get(),
|
||||
postRepository = get(),
|
||||
themeRepository = get(),
|
||||
@ -199,4 +200,13 @@ val commonUiModule = module {
|
||||
commentRepository = get(),
|
||||
)
|
||||
}
|
||||
factory<SelectCommunityMviModel> {
|
||||
SelectCommunityViewModel(
|
||||
mvi = DefaultMviModel(SelectCommunityMviModel.UiState()),
|
||||
identityRepository = get(),
|
||||
communityRepository = get(),
|
||||
settingsRepository = get(),
|
||||
notificationCenter = get(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation.Navigat
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateReportMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems.SavedItemsMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
@ -61,7 +62,6 @@ expect fun getCreateCommentViewModel(
|
||||
): CreateCommentMviModel
|
||||
|
||||
expect fun getCreatePostViewModel(
|
||||
communityId: Int?,
|
||||
editedPostId: Int?,
|
||||
): CreatePostMviModel
|
||||
|
||||
@ -81,4 +81,6 @@ expect fun getCreateReportViewModel(
|
||||
@Composable
|
||||
expect fun getCustomTextToolbar(
|
||||
onSearch: () -> Unit,
|
||||
): TextToolbar
|
||||
): TextToolbar
|
||||
|
||||
expect fun getSelectCommunityViewModel(): SelectCommunityMviModel
|
@ -81,6 +81,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Comment
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
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
|
||||
@ -407,37 +409,76 @@ class PostDetailScreen(
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.CrossPost,
|
||||
stringResource(MR.strings.post_action_cross_post)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
if (uiState.post.creator?.id == uiState.currentUserId && !isOnOtherInstance) {
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { idx ->
|
||||
when (idx) {
|
||||
4 -> model.reduce(PostDetailMviModel.Intent.DeletePost)
|
||||
OptionId.Delete -> model.reduce(PostDetailMviModel.Intent.DeletePost)
|
||||
|
||||
3 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = uiState.post,
|
||||
)
|
||||
CreatePostScreen(editedPost = uiState.post)
|
||||
)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(postId = uiState.post.id)
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreatePostScreen(crossPost = uiState.post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = uiState.post
|
||||
}
|
||||
|
||||
else -> model.reduce(PostDetailMviModel.Intent.SharePost)
|
||||
OptionId.Share -> model.reduce(PostDetailMviModel.Intent.SharePost)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
@ -657,24 +698,44 @@ class PostDetailScreen(
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
if (comment.creator?.id == uiState.currentUserId) {
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(
|
||||
model
|
||||
) { optionId ->
|
||||
when (optionId) {
|
||||
3 -> model.reduce(
|
||||
OptionId.Delete -> model.reduce(
|
||||
PostDetailMviModel.Intent.DeleteComment(
|
||||
comment.id
|
||||
)
|
||||
)
|
||||
|
||||
2 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
@ -683,7 +744,7 @@ class PostDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
@ -692,9 +753,11 @@ class PostDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = comment
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -762,22 +825,42 @@ class PostDetailScreen(
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
if (comment.creator?.id == uiState.currentUserId) {
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
3 -> model.reduce(
|
||||
OptionId.Delete -> model.reduce(
|
||||
PostDetailMviModel.Intent.DeleteComment(
|
||||
comment.id
|
||||
)
|
||||
)
|
||||
|
||||
2 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
@ -786,7 +869,7 @@ class PostDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
@ -795,9 +878,11 @@ class PostDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = comment
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -55,6 +55,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.Co
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
@ -299,13 +301,28 @@ class SavedItemsScreen : Screen {
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
2 -> {
|
||||
OptionId.Report -> {
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
@ -313,17 +330,19 @@ class SavedItemsScreen : Screen {
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.Share -> {
|
||||
model.reduce(
|
||||
SavedItemsMviModel.Intent.SharePost(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -393,12 +412,22 @@ class SavedItemsScreen : Screen {
|
||||
navigatorCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
1 -> {
|
||||
OptionId.Report -> {
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
@ -406,9 +435,11 @@ class SavedItemsScreen : Screen {
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = comment
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity
|
||||
|
||||
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.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.shimmerEffect
|
||||
|
||||
@Composable
|
||||
fun CommunityItemPlaceholder() {
|
||||
Row(
|
||||
modifier = Modifier.padding(
|
||||
vertical = Spacing.xs,
|
||||
horizontal = Spacing.s,
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(IconSize.m)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier.padding(start = Spacing.xs),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(50.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(30.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(CornerSize.s))
|
||||
.shimmerEffect()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,159 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity
|
||||
|
||||
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.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
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.graphics.Color
|
||||
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.CommunityItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getSelectCommunityViewModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
class SelectCommunityDialog : Screen {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
override fun Content() {
|
||||
val model = rememberScreenModel { getSelectCommunityViewModel() }
|
||||
model.bindToLifecycle(key)
|
||||
val uiState by model.uiState.collectAsState()
|
||||
val notificationCenter = remember { getNotificationCenter() }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = rememberCallback {
|
||||
model.reduce(SelectCommunityMviModel.Intent.SetSearch(""))
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.CloseDialog)
|
||||
?.invoke(Unit)
|
||||
},
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = MaterialTheme.colorScheme.surface)
|
||||
.padding(vertical = Spacing.s),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.s),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(MR.strings.dialog_title_select_community),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(Spacing.s))
|
||||
|
||||
TextField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
),
|
||||
label = {
|
||||
Text(text = stringResource(MR.strings.explore_search_placeholder))
|
||||
},
|
||||
singleLine = true,
|
||||
value = uiState.searchText,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = KeyboardType.Text,
|
||||
),
|
||||
onValueChange = { value ->
|
||||
model.reduce(SelectCommunityMviModel.Intent.SetSearch(value))
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(SelectCommunityMviModel.Intent.SetSearch(""))
|
||||
}
|
||||
},
|
||||
),
|
||||
imageVector = if (uiState.searchText.isEmpty()) Icons.Default.Search else Icons.Default.Clear,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 500.dp, max = 500.dp)
|
||||
.padding(horizontal = Spacing.m)
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
) {
|
||||
if (uiState.communities.isEmpty() && uiState.initial) {
|
||||
items(5) {
|
||||
CommunityItemPlaceholder()
|
||||
}
|
||||
}
|
||||
items(uiState.communities, { it.id }) { community ->
|
||||
CommunityItem(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.onClick(rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.SelectCommunity
|
||||
)
|
||||
?.invoke(community)
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.CloseDialog
|
||||
)
|
||||
?.invoke(Unit)
|
||||
}),
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
community = community,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
model.reduce(SelectCommunityMviModel.Intent.SetSearch(""))
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.CloseDialog)
|
||||
?.invoke(Unit)
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.button_close))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity
|
||||
|
||||
import cafe.adriel.voyager.core.model.ScreenModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
|
||||
interface SelectCommunityMviModel :
|
||||
MviModel<SelectCommunityMviModel.Intent, SelectCommunityMviModel.UiState, SelectCommunityMviModel.Effect>,
|
||||
ScreenModel {
|
||||
sealed interface Intent {
|
||||
data class SetSearch(val value: String) : Intent
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val initial: Boolean = true,
|
||||
val communities: List<CommunityModel> = emptyList(),
|
||||
val searchText: String = "",
|
||||
val autoLoadImages: Boolean = true,
|
||||
)
|
||||
|
||||
sealed interface Effect
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity
|
||||
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.CommunityRepository
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SelectCommunityViewModel(
|
||||
private val mvi: DefaultMviModel<SelectCommunityMviModel.Intent, SelectCommunityMviModel.UiState, SelectCommunityMviModel.Effect>,
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val communityRepository: CommunityRepository,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
private val notificationCenter: NotificationCenter,
|
||||
) : SelectCommunityMviModel,
|
||||
MviModel<SelectCommunityMviModel.Intent, SelectCommunityMviModel.UiState, SelectCommunityMviModel.Effect> by mvi {
|
||||
|
||||
private var communities: List<CommunityModel> = emptyList()
|
||||
private var debounceJob: Job? = null
|
||||
|
||||
override fun onStarted() {
|
||||
mvi.onStarted()
|
||||
mvi.scope?.launch {
|
||||
settingsRepository.currentSettings.onEach { settings ->
|
||||
mvi.updateState { it.copy(autoLoadImages = settings.autoLoadImages) }
|
||||
}.launchIn(this)
|
||||
}
|
||||
if (communities.isEmpty()) {
|
||||
populate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun reduce(intent: SelectCommunityMviModel.Intent) {
|
||||
when (intent) {
|
||||
is SelectCommunityMviModel.Intent.SetSearch -> setSearch(intent.value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setSearch(value: String) {
|
||||
debounceJob?.cancel()
|
||||
mvi.updateState { it.copy(searchText = value) }
|
||||
debounceJob = mvi.scope?.launch(Dispatchers.IO) {
|
||||
delay(1_000)
|
||||
mvi.updateState {
|
||||
val filtered = filterCommunities()
|
||||
it.copy(communities = filtered)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun populate() {
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
val auth = identityRepository.authToken.value
|
||||
communities = communityRepository.getSubscribed(auth).sortedBy { it.name }
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
initial = false,
|
||||
communities = communities,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun filterCommunities(): List<CommunityModel> {
|
||||
val searchText = uiState.value.searchText
|
||||
val res = if (searchText.isNotEmpty()) {
|
||||
communities.filter { it.name.contains(searchText) }
|
||||
} else {
|
||||
communities
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
@ -32,6 +32,7 @@ interface UserDetailMviModel :
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val currentUserId: Int? = null,
|
||||
val section: UserDetailSection = UserDetailSection.Posts,
|
||||
val sortType: SortType = SortType.Active,
|
||||
val refreshing: Boolean = false,
|
||||
|
@ -69,6 +69,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Comment
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ProgressHud
|
||||
@ -76,6 +78,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.UserHeader
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createpost.CreatePostScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getFabNestedScrollConnection
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
@ -317,17 +320,24 @@ class UserDetailScreen(
|
||||
user = uiState.user,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
options = listOf(
|
||||
stringResource(MR.strings.community_detail_block),
|
||||
stringResource(MR.strings.community_detail_block_instance),
|
||||
Option(
|
||||
OptionId.Block,
|
||||
stringResource(MR.strings.community_detail_block)
|
||||
),
|
||||
Option(
|
||||
OptionId.BlockInstance,
|
||||
stringResource(MR.strings.community_detail_block_instance)
|
||||
),
|
||||
),
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
1 -> model.reduce(UserDetailMviModel.Intent.BlockInstance)
|
||||
else -> model.reduce(UserDetailMviModel.Intent.Block)
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.BlockInstance -> model.reduce(UserDetailMviModel.Intent.BlockInstance)
|
||||
OptionId.Block -> model.reduce(UserDetailMviModel.Intent.Block)
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -482,13 +492,36 @@ class UserDetailScreen(
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.CrossPost,
|
||||
stringResource(MR.strings.post_action_cross_post)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
@ -497,13 +530,22 @@ class UserDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
else -> model.reduce(
|
||||
OptionId.Share -> model.reduce(
|
||||
UserDetailMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -653,12 +695,24 @@ class UserDetailScreen(
|
||||
?.push(CommunityDetailScreen(community))
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
1 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
@ -667,9 +721,11 @@ class UserDetailScreen(
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = comment
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -86,6 +86,11 @@ class UserDetailViewModel(
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
if (uiState.value.currentUserId == null) {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
val user = siteRepository.getCurrentUser(auth)
|
||||
mvi.updateState { it.copy(currentUserId = user?.id ?: 0) }
|
||||
}
|
||||
}
|
||||
if (uiState.value.posts.isEmpty()) {
|
||||
refresh(initial = true)
|
||||
|
@ -19,6 +19,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation.Navigat
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.report.CreateReportMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.saveditems.SavedItemsMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.selectcommunity.SelectCommunityMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailMviModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
|
||||
@ -71,10 +72,9 @@ actual fun getCreateCommentViewModel(
|
||||
CommonUiViewModelHelper.getCreateCommentModel(postId, parentId, editedCommentId)
|
||||
|
||||
actual fun getCreatePostViewModel(
|
||||
communityId: Int?,
|
||||
editedPostId: Int?,
|
||||
): CreatePostMviModel =
|
||||
CommonUiViewModelHelper.getCreatePostModel(communityId, editedPostId)
|
||||
CommonUiViewModelHelper.getCreatePostModel(editedPostId)
|
||||
|
||||
actual fun getZoomableImageViewModel(): ZoomableImageMviModel =
|
||||
CommonUiViewModelHelper.zoomableImageModel
|
||||
@ -93,6 +93,9 @@ actual fun getCreateReportViewModel(
|
||||
commentId: Int?,
|
||||
): CreateReportMviModel = CommonUiViewModelHelper.getCreateReportModel(postId, commentId)
|
||||
|
||||
actual fun getSelectCommunityViewModel(): SelectCommunityMviModel =
|
||||
CommonUiViewModelHelper.selectCommunityViewModel
|
||||
|
||||
object CommonUiViewModelHelper : KoinComponent {
|
||||
|
||||
val navigationCoordinator: NavigationCoordinator by inject()
|
||||
@ -101,6 +104,7 @@ object CommonUiViewModelHelper : KoinComponent {
|
||||
val zoomableImageModel: ZoomableImageMviModel by inject()
|
||||
val savedItemsViewModel: SavedItemsMviModel by inject()
|
||||
val modalDrawerViewModel: ModalDrawerMviModel by inject()
|
||||
val selectCommunityViewModel: SelectCommunityMviModel by inject()
|
||||
|
||||
fun getPostDetailModel(
|
||||
post: PostModel,
|
||||
@ -155,9 +159,9 @@ object CommonUiViewModelHelper : KoinComponent {
|
||||
return model
|
||||
}
|
||||
|
||||
fun getCreatePostModel(communityId: Int?, editedPostId: Int?): CreatePostMviModel {
|
||||
fun getCreatePostModel(editedPostId: Int?): CreatePostMviModel {
|
||||
val model: CreatePostMviModel by inject(
|
||||
parameters = { parametersOf(communityId, editedPostId) }
|
||||
parameters = { parametersOf(editedPostId) }
|
||||
)
|
||||
return model
|
||||
}
|
||||
|
@ -22,4 +22,5 @@ object NotificationCenterContractKeys {
|
||||
const val MultiCommunityCreated = "multiCommunityCreated"
|
||||
const val ResetContents = "resetContents"
|
||||
const val CloseDialog = "closeDialog"
|
||||
const val SelectCommunity = "selectCommunity"
|
||||
}
|
@ -60,6 +60,8 @@ 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.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
@ -247,16 +249,18 @@ class PostListScreen : Screen {
|
||||
}
|
||||
},
|
||||
)
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(PostListMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
}
|
||||
},
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
this += FloatingActionButtonMenuItem(
|
||||
icon = Icons.Default.ClearAll,
|
||||
text = stringResource(MR.strings.action_clear_read),
|
||||
onSelected = rememberCallback {
|
||||
model.reduce(PostListMviModel.Intent.ClearRead)
|
||||
scope.launch {
|
||||
lazyListState.scrollToItem(0)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -403,44 +407,97 @@ class PostListScreen : Screen {
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_hide))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Hide,
|
||||
stringResource(MR.strings.post_action_hide)
|
||||
)
|
||||
)
|
||||
}
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.CrossPost,
|
||||
stringResource(MR.strings.post_action_cross_post)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
if (post.creator?.id == uiState.currentUserId) {
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionIdx ->
|
||||
when (optionIdx) {
|
||||
5 -> model.reduce(
|
||||
onOptionSelected = rememberCallbackArgs(model) { optinId ->
|
||||
when (optinId) {
|
||||
OptionId.Delete -> model.reduce(
|
||||
PostListMviModel.Intent.DeletePost(post.id)
|
||||
)
|
||||
|
||||
4 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
1 -> model.reduce(PostListMviModel.Intent.Hide(post.id))
|
||||
OptionId.Hide -> model.reduce(
|
||||
PostListMviModel.Intent.Hide(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
|
||||
else -> model.reduce(
|
||||
OptionId.Share -> model.reduce(
|
||||
PostListMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -17,7 +17,7 @@ import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
@ -70,7 +70,7 @@ internal fun PostsTopBar(
|
||||
}
|
||||
|
||||
else -> {
|
||||
Box(modifier = Modifier.size(24.dp))
|
||||
Box(modifier = Modifier.size(IconSize.m))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -19,6 +19,7 @@ import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PlaceholderImage
|
||||
@ -118,7 +119,7 @@ internal fun ChatCard(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val buttonModifier = Modifier.size(24.dp).padding(3.25.dp)
|
||||
val buttonModifier = Modifier.size(IconSize.m).padding(3.25.dp)
|
||||
Icon(
|
||||
modifier = buttonModifier.padding(1.dp),
|
||||
imageVector = Icons.Default.Schedule,
|
||||
|
@ -42,6 +42,8 @@ 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.CommentCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommentCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SectionSelector
|
||||
@ -230,18 +232,38 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionIdx ->
|
||||
when (optionIdx) {
|
||||
3 -> model.reduce(
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Delete -> model.reduce(
|
||||
ProfileLoggedMviModel.Intent.DeletePost(post.id)
|
||||
)
|
||||
|
||||
2 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
@ -249,13 +271,15 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = post
|
||||
}
|
||||
|
||||
else -> model.reduce(
|
||||
OptionId.Share -> model.reduce(
|
||||
ProfileLoggedMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
},
|
||||
)
|
||||
@ -330,13 +354,28 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_see_raw))
|
||||
add(stringResource(MR.strings.post_action_edit))
|
||||
add(stringResource(MR.strings.comment_action_delete))
|
||||
add(
|
||||
Option(
|
||||
OptionId.SeeRaw,
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Edit,
|
||||
stringResource(MR.strings.post_action_edit)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Delete,
|
||||
stringResource(MR.strings.comment_action_delete)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Delete -> {
|
||||
model.reduce(
|
||||
ProfileLoggedMviModel.Intent.DeleteComment(
|
||||
comment.id
|
||||
@ -344,7 +383,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
@ -352,9 +391,11 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
OptionId.SeeRaw -> {
|
||||
rawContent = comment
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -46,6 +46,7 @@ val exploreTabModule = module {
|
||||
community = params[0],
|
||||
postRepository = get(),
|
||||
identityRepository = get(),
|
||||
siteRepository = get(),
|
||||
themeRepository = get(),
|
||||
shareHelper = get(),
|
||||
settingsRepository = get(),
|
||||
|
@ -17,7 +17,7 @@ import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.rememberCallback
|
||||
@ -69,7 +69,7 @@ internal fun ExploreTopBar(
|
||||
}
|
||||
|
||||
else -> {
|
||||
Box(modifier = Modifier.size(24.dp))
|
||||
Box(modifier = Modifier.size(IconSize.m))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -24,6 +24,7 @@ interface MultiCommunityMviModel :
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val currentUserId: Int? = null,
|
||||
val refreshing: Boolean = false,
|
||||
val loading: Boolean = false,
|
||||
val canFetchMore: Boolean = true,
|
||||
|
@ -61,6 +61,8 @@ 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.FloatingActionButtonMenu
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.FloatingActionButtonMenuItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Option
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.OptionId
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
@ -375,13 +377,30 @@ class MultiCommunityScreen(
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(stringResource(MR.strings.post_action_share))
|
||||
add(stringResource(MR.strings.post_action_hide))
|
||||
add(stringResource(MR.strings.post_action_report))
|
||||
add(
|
||||
Option(
|
||||
OptionId.Share,
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Hide,
|
||||
stringResource(MR.strings.post_action_hide)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.Report,
|
||||
stringResource(MR.strings.post_action_report)
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOptionSelected = { optionIdx ->
|
||||
when (optionIdx) {
|
||||
2 -> {
|
||||
onOptionSelected = { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
@ -389,15 +408,17 @@ class MultiCommunityScreen(
|
||||
)
|
||||
}
|
||||
|
||||
1 -> model.reduce(
|
||||
OptionId.Hide -> model.reduce(
|
||||
MultiCommunityMviModel.Intent.Hide(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
|
||||
else -> model.reduce(
|
||||
OptionId.Share -> model.reduce(
|
||||
MultiCommunityMviModel.Intent.SharePost(post.id)
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.imageUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.shareUrl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toSortType
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.PostRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.repository.SiteRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.feature.search.multicommunity.utils.MultiCommunityPaginator
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
@ -29,6 +30,7 @@ class MultiCommunityViewModel(
|
||||
private val community: MultiCommunityModel,
|
||||
private val postRepository: PostRepository,
|
||||
private val identityRepository: IdentityRepository,
|
||||
private val siteRepository: SiteRepository,
|
||||
private val themeRepository: ThemeRepository,
|
||||
private val shareHelper: ShareHelper,
|
||||
private val settingsRepository: SettingsRepository,
|
||||
@ -72,6 +74,11 @@ class MultiCommunityViewModel(
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
if (uiState.value.currentUserId == null) {
|
||||
val auth = identityRepository.authToken.value.orEmpty()
|
||||
val user = siteRepository.getCurrentUser(auth)
|
||||
mvi.updateState { it.copy(currentUserId = user?.id ?: 0) }
|
||||
}
|
||||
}
|
||||
|
||||
mvi.scope?.launch(Dispatchers.IO) {
|
||||
|
@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
|
||||
@Composable
|
||||
@ -32,7 +32,7 @@ internal fun SettingsHeader(
|
||||
) {
|
||||
if (icon != null) {
|
||||
Icon(
|
||||
modifier = Modifier.size(24.dp),
|
||||
modifier = Modifier.size(IconSize.m),
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
)
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Comment body</string>
|
||||
<string name="create_comment_title">New comment</string>
|
||||
<string name="create_post_body">Post body</string>
|
||||
<string name="create_post_community">Community</string>
|
||||
<string name="create_post_cross_post_text">Cross posted from:</string>
|
||||
<string name="create_post_name">Post title</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Editor</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Change instance</string>
|
||||
<string name="dialog_title_raw_content">Raw content</string>
|
||||
<string name="dialog_title_select_community">Select a community</string>
|
||||
<string name="explore_result_type_all">All</string>
|
||||
<string name="explore_result_type_comments">Comments</string>
|
||||
<string name="explore_result_type_communities">Communities</string>
|
||||
@ -131,7 +134,8 @@
|
||||
<string name="navigation_profile">Profile</string>
|
||||
<string name="navigation_search">Explore</string>
|
||||
<string name="navigation_settings">Settings</string>
|
||||
<string name="post_action_edit">Edit</string>
|
||||
<string name="post_action_cross_post">Cross-post…</string>
|
||||
<string name="post_action_edit">Edit…</string>
|
||||
<string name="post_action_hide">Hide</string>
|
||||
<string name="post_action_report">Report…</string>
|
||||
<string name="post_action_see_raw">View raw…</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Kommentartext</string>
|
||||
<string name="create_comment_title">Neuer Kommentar</string>
|
||||
<string name="create_post_body">Beitragstext</string>
|
||||
<string name="create_post_community">Community</string>
|
||||
<string name="create_post_cross_post_text">Cross-gepostet von:</string>
|
||||
<string name="create_post_name">Beitragstitel</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Redakteur</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Instanz ändern</string>
|
||||
<string name="dialog_title_raw_content">Rohinhalt</string>
|
||||
<string name="dialog_title_select_community">Wählen Sie eine Community aus</string>
|
||||
<string name="explore_result_type_all">Alle</string>
|
||||
<string name="explore_result_type_comments">Kommentare</string>
|
||||
<string name="explore_result_type_communities">Communitys</string>
|
||||
@ -124,7 +127,8 @@
|
||||
<string name="navigation_profile">Profil</string>
|
||||
<string name="navigation_search">Erkunden</string>
|
||||
<string name="navigation_settings">Einstellungen</string>
|
||||
<string name="post_action_edit">Bearbeiten</string>
|
||||
<string name="post_action_cross_post">Cross-post</string>
|
||||
<string name="post_action_edit">Bearbeiten…</string>
|
||||
<string name="post_action_hide">Verstecken</string>
|
||||
<string name="post_action_report">Bericht…</string>
|
||||
<string name="post_action_see_raw">Roh ansehen…</string>
|
||||
|
@ -24,6 +24,8 @@
|
||||
<string name="community_info_subscribers">συνδρομητές</string>
|
||||
<string name="community_info_weekly_active_users">ενεργοί χρήστες (εβδομάδα)</string>
|
||||
<string name="create_comment_body">Κείμενο σχολίου</string>
|
||||
<string name="create_post_community">Κοινότητα</string>
|
||||
<string name="create_post_cross_post_text">Διασταυρούμενη από:</string>
|
||||
<string name="create_comment_title">Νέο σχόλιο</string>
|
||||
<string name="create_post_body">Κείμενο ανάρτησης</string>
|
||||
<string name="create_post_name">Τίτλος ανάρτησης</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Αλλαγή παραδείγματος</string>
|
||||
<string name="dialog_title_raw_content">Ακατέργαστο περιεχόμενο</string>
|
||||
<string name="dialog_title_select_community">Επιλέξε μια κοινότητα</string>
|
||||
<string name="explore_result_type_all">Όλα</string>
|
||||
<string name="explore_result_type_comments">Σχόλια</string>
|
||||
<string name="explore_result_type_communities">Κοινότητες</string>
|
||||
@ -124,11 +127,12 @@
|
||||
<string name="navigation_profile">Προφίλ</string>
|
||||
<string name="navigation_search">Εξερεύνηση</string>
|
||||
<string name="navigation_settings">Ρυθμίσεις</string>
|
||||
<string name="post_action_edit">Επεξεργασία</string>
|
||||
<string name="post_action_hide">Απόκρυψη</string>
|
||||
<string name="post_action_report">Αναφορά…</string>
|
||||
<string name="post_action_cross_post">Διασταύρωσε ανάρτηση…</string>
|
||||
<string name="post_action_edit">Επεξεργασία…</string>
|
||||
<string name="post_action_hide">Απόκρυψε</string>
|
||||
<string name="post_action_report">Αναφόρησε…</string>
|
||||
<string name="post_action_see_raw">Προβολή ακατέργαστου…</string>
|
||||
<string name="post_action_share">Κοινοποίηση…</string>
|
||||
<string name="post_action_share">Κοινοποίησε…</string>
|
||||
<string name="post_detail_cross_posts">επίσης αναρτήθηκε σε:</string>
|
||||
<string name="post_detail_load_more_comments">Φόρτωση περισσότερων σχολίων…</string>
|
||||
<string name="post_hour_short">ώρ</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Texto comentario</string>
|
||||
<string name="create_comment_title">Nuevo comentario</string>
|
||||
<string name="create_post_body">Texto publicación</string>
|
||||
<string name="create_post_community">Comunidad</string>
|
||||
<string name="create_post_cross_post_text">Publicación cruzada desde:</string>
|
||||
<string name="create_post_name">Título publicación</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Editor</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Cambiar de instancia</string>
|
||||
<string name="dialog_title_raw_content">Contenido raw</string>
|
||||
<string name="dialog_title_select_community">Seleccionar una comunidad</string>
|
||||
<string name="explore_result_type_all">Todos</string>
|
||||
<string name="explore_result_type_comments">Comentarios</string>
|
||||
<string name="explore_result_type_communities">Comunidades</string>
|
||||
@ -124,7 +127,8 @@
|
||||
<string name="navigation_profile">Perfil</string>
|
||||
<string name="navigation_search">Descubre</string>
|
||||
<string name="navigation_settings">Ajustes</string>
|
||||
<string name="post_action_edit">Modificar</string>
|
||||
<string name="post_action_cross_post">Publicación cruzada…</string>
|
||||
<string name="post_action_edit">Modificar…</string>
|
||||
<string name="post_action_hide">Esconder</string>
|
||||
<string name="post_action_report">Crear informe…</string>
|
||||
<string name="post_action_see_raw">Ver raw…</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Texte du commentaire</string>
|
||||
<string name="create_comment_title">Nouveau commentaire</string>
|
||||
<string name="create_post_body">Texte de la publication</string>
|
||||
<string name="create_post_community">Communauté</string>
|
||||
<string name="create_post_cross_post_text">Publication croisée à partir de:</string>
|
||||
<string name="create_post_name">Titre de la publication</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Éditeur</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Changer d\'instance</string>
|
||||
<string name="dialog_title_raw_content">Contenu brut</string>
|
||||
<string name="dialog_title_select_community">Sélectionner une communauté</string>
|
||||
<string name="explore_result_type_all">Tous</string>
|
||||
<string name="explore_result_type_comments">Commentaires</string>
|
||||
<string name="explore_result_type_communities">Communautés</string>
|
||||
@ -124,7 +127,8 @@
|
||||
<string name="navigation_profile">Profil</string>
|
||||
<string name="navigation_search">Explorer</string>
|
||||
<string name="navigation_settings">Réglages</string>
|
||||
<string name="post_action_edit">Éditer</string>
|
||||
<string name="post_action_cross_post">Publication croisée…</string>
|
||||
<string name="post_action_edit">Éditer…</string>
|
||||
<string name="post_action_hide">Cacher</string>
|
||||
<string name="post_action_report">Signaler</string>
|
||||
<string name="post_action_see_raw">Voir brut…</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Testo commento</string>
|
||||
<string name="create_comment_title">Nuovo commento</string>
|
||||
<string name="create_post_body">Testo post</string>
|
||||
<string name="create_post_community">Comunità</string>
|
||||
<string name="create_post_cross_post_text">Cross-post da:</string>
|
||||
<string name="create_post_name">Titolo post</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Editor</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Cambia istanza</string>
|
||||
<string name="dialog_title_raw_content">Contenuto grezzo</string>
|
||||
<string name="dialog_title_select_community">Seleziona comunità</string>
|
||||
<string name="explore_result_type_all">Tutti</string>
|
||||
<string name="explore_result_type_comments">Commenti</string>
|
||||
<string name="explore_result_type_communities">Comunità</string>
|
||||
@ -124,7 +127,8 @@
|
||||
<string name="navigation_profile">Profilo</string>
|
||||
<string name="navigation_search">Esplora</string>
|
||||
<string name="navigation_settings">Impostazioni</string>
|
||||
<string name="post_action_edit">Modifica</string>
|
||||
<string name="post_action_cross_post">Cross-post…</string>
|
||||
<string name="post_action_edit">Modifica…</string>
|
||||
<string name="post_action_hide">Nascondi</string>
|
||||
<string name="post_action_report">Segnala…</string>
|
||||
<string name="post_action_see_raw">Vedi raw…</string>
|
||||
|
@ -23,8 +23,10 @@
|
||||
<string name="community_info_posts">berichten</string>
|
||||
<string name="community_info_subscribers">abonnees</string>
|
||||
<string name="community_info_weekly_active_users">actieve gebruikers (week)</string>
|
||||
<string name="create_comment_body">Reactie body</string>
|
||||
<string name="create_comment_title">Nieuwe opmerking</string>
|
||||
<string name="create_comment_body">Commentaar body</string>
|
||||
<string name="create_post_community">Gemeenschap</string>
|
||||
<string name="create_post_cross_post_text">Crosspost van:</string>
|
||||
<string name="create_comment_title">Nieuw commentaar</string>
|
||||
<string name="create_post_body">Bericht body</string>
|
||||
<string name="create_post_name">Bericht titel</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Instantie wijzigen</string>
|
||||
<string name="dialog_title_raw_content">Content</string>
|
||||
<string name="dialog_title_select_community">Selecteer een gemeenschap</string>
|
||||
<string name="explore_result_type_all">Alle</string>
|
||||
<string name="explore_result_type_comments">Opmerkingen</string>
|
||||
<string name="explore_result_type_communities">Samenleving</string>
|
||||
@ -132,13 +135,14 @@
|
||||
<string name="navigation_profile">Profiel</string>
|
||||
<string name="navigation_search">Ontdekken</string>
|
||||
<string name="navigation_settings">Instellingen</string>
|
||||
<string name="post_action_edit">Bewerk</string>
|
||||
<string name="post_action_cross_post">Crosspost…</string>
|
||||
<string name="post_action_edit">Bewerk…</string>
|
||||
<string name="post_action_hide">Verbergen</string>
|
||||
<string name="post_action_report">Verslag</string>
|
||||
<string name="post_action_see_raw">Toon raw</string>
|
||||
<string name="post_action_share">Delen</string>
|
||||
<string name="post_action_report">Verslag…</string>
|
||||
<string name="post_action_see_raw">Toon raw…</string>
|
||||
<string name="post_action_share">Delen…</string>
|
||||
<string name="post_detail_cross_posts">ook geplaatst op:</string>
|
||||
<string name="post_detail_load_more_comments">Meer reacties laden</string>
|
||||
<string name="post_detail_load_more_comments">Meer reacties laden…</string>
|
||||
<string name="post_hour_short">u</string>
|
||||
<string name="post_minute_short">m</string>
|
||||
<string name="post_second_short">s</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Texto do comentário</string>
|
||||
<string name="create_comment_title">Novo comentário</string>
|
||||
<string name="create_post_body">Texto da publicação</string>
|
||||
<string name="create_post_community">Comunidade</string>
|
||||
<string name="create_post_cross_post_text">Publicação cruzada de:</string>
|
||||
<string name="create_post_name">Título da publicação</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Editor</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Mudar instância</string>
|
||||
<string name="dialog_title_raw_content">Conteúdo bruto</string>
|
||||
<string name="dialog_title_select_community">Selecionar uma comunidade</string>
|
||||
<string name="explore_result_type_all">Todos</string>
|
||||
<string name="explore_result_type_comments">Comentários</string>
|
||||
<string name="explore_result_type_communities">Comunidades</string>
|
||||
@ -122,7 +125,8 @@
|
||||
<string name="navigation_profile">Perfil</string>
|
||||
<string name="navigation_search">Explorar</string>
|
||||
<string name="navigation_settings">Configurações</string>
|
||||
<string name="post_action_edit">Modificar</string>
|
||||
<string name="post_action_cross_post">Publicação cruzada…</string>
|
||||
<string name="post_action_edit">Modificar…</string>
|
||||
<string name="post_action_hide">Esconder</string>
|
||||
<string name="post_action_report">Denunciar…</string>
|
||||
<string name="post_action_see_raw">Ver conteúdo bruto</string>
|
||||
|
@ -26,6 +26,8 @@
|
||||
<string name="create_comment_body">Text comentariului</string>
|
||||
<string name="create_comment_title">Nou comentariu</string>
|
||||
<string name="create_post_body">Text postării</string>
|
||||
<string name="create_post_community">Community</string>
|
||||
<string name="create_post_cross_post_text">Postare încrucișată din:</string>
|
||||
<string name="create_post_name">Titlu postării</string>
|
||||
<string name="create_post_nsfw">NSFW</string>
|
||||
<string name="create_post_tab_editor">Editor</string>
|
||||
@ -40,6 +42,7 @@
|
||||
<string name="dialog_raw_content_url">URL</string>
|
||||
<string name="dialog_title_change_instance">Schimbă instanță</string>
|
||||
<string name="dialog_title_raw_content">Conținut brut</string>
|
||||
<string name="dialog_title_select_community">Selectează comunitate</string>
|
||||
<string name="explore_result_type_all">Toate</string>
|
||||
<string name="explore_result_type_comments">Comentarii</string>
|
||||
<string name="explore_result_type_communities">Comunități</string>
|
||||
@ -123,10 +126,11 @@
|
||||
<string name="navigation_profile">Profil</string>
|
||||
<string name="navigation_search">Exploră</string>
|
||||
<string name="navigation_settings">Setări</string>
|
||||
<string name="post_action_edit">Editează</string>
|
||||
<string name="post_action_cross_post">Postare încrucișată…</string>
|
||||
<string name="post_action_edit">Editează…</string>
|
||||
<string name="post_action_hide">Ascunde</string>
|
||||
<string name="post_action_report">Reportează…</string>
|
||||
<string name="post_action_see_raw">Vizualizare bruta…</string>
|
||||
<string name="post_action_see_raw">Vizualizare brută…</string>
|
||||
<string name="post_action_share">Partajează…</string>
|
||||
<string name="post_detail_cross_posts">postat și în:</string>
|
||||
<string name="post_detail_load_more_comments">Încărcă mai multe comentări…</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user