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