mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-09 08:48:40 +01:00
feat: double click management (#130)
This commit is contained in:
parent
aecf2549fb
commit
e474c9227d
@ -26,6 +26,7 @@ object IconSize {
|
||||
val s = 20.dp
|
||||
val m = 26.dp
|
||||
val l = 30.dp
|
||||
val xl = 46.dp
|
||||
val xxl = 60.dp
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ fun FloatingActionButtonMenu(
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
fabExpanded = false
|
||||
item.onSelected?.invoke()
|
||||
},
|
||||
|
@ -111,8 +111,8 @@ class InboxChatScreen(
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
|
@ -46,6 +46,7 @@ interface CommunityDetailMviModel :
|
||||
val blurNsfw: Boolean = true,
|
||||
val currentUserId: Int? = null,
|
||||
val swipeActionsEnabled: Boolean = true,
|
||||
val doubleTapActionEnabled: Boolean = false,
|
||||
val postLayout: PostLayout = PostLayout.Card,
|
||||
val fullHeightImages: Boolean = true,
|
||||
val separateUpAndDownVotes: Boolean = false,
|
||||
|
@ -237,7 +237,7 @@ class CommunityDetailScreen(
|
||||
if (!isOnOtherInstance && uiState.isLogged) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
when (uiState.community.subscribed) {
|
||||
true -> model.reduce(CommunityDetailMviModel.Intent.Unsubscribe)
|
||||
false -> model.reduce(CommunityDetailMviModel.Intent.Subscribe)
|
||||
@ -259,11 +259,11 @@ class CommunityDetailScreen(
|
||||
// sort button
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -297,7 +297,7 @@ class CommunityDetailScreen(
|
||||
modifier = Modifier.onGloballyPositioned {
|
||||
optionsOffset = it.positionInParent()
|
||||
}.padding(start = Spacing.s).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = true
|
||||
},
|
||||
),
|
||||
@ -321,7 +321,7 @@ class CommunityDetailScreen(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = false
|
||||
when (option.id) {
|
||||
OptionId.BlockInstance -> model.reduce(
|
||||
@ -333,19 +333,17 @@ class CommunityDetailScreen(
|
||||
)
|
||||
|
||||
OptionId.InfoInstance -> {
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
InstanceInfoScreen(
|
||||
url = uiState.community.instanceUrl,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.pushScreen(
|
||||
InstanceInfoScreen(
|
||||
url = uiState.community.instanceUrl,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Info -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CommunityInfoScreen(uiState.community),
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CommunityInfoScreen(uiState.community),
|
||||
)
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
@ -359,12 +357,11 @@ class CommunityDetailScreen(
|
||||
}
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
if (navigationCoordinator.canPop) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -437,7 +434,7 @@ class CommunityDetailScreen(
|
||||
val screen = CreatePostScreen(
|
||||
communityId = uiState.community.id,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -476,8 +473,7 @@ class CommunityDetailScreen(
|
||||
community = uiState.community,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.pushScreen(ZoomableImageScreen(url))
|
||||
},
|
||||
)
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
@ -559,15 +555,27 @@ class CommunityDetailScreen(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
otherInstance = otherInstanceName,
|
||||
),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled || !uiState.isLogged || isOnOtherInstance) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
CommunityDetailMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstanceName,
|
||||
@ -609,8 +617,7 @@ class CommunityDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs(model) { url ->
|
||||
@ -619,7 +626,7 @@ class CommunityDetailScreen(
|
||||
post.id
|
||||
)
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -680,24 +687,21 @@ class CommunityDetailScreen(
|
||||
)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
|
@ -66,6 +66,7 @@ class CommunityDetailViewModel(
|
||||
it.copy(
|
||||
blurNsfw = settings.blurNsfw,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
sortType = settings.defaultPostSortType.toSortType(),
|
||||
fullHeightImages = settings.fullHeightImages,
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
|
@ -21,7 +21,6 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepos
|
||||
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.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommentModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
@ -42,6 +41,7 @@ fun CommentCard(
|
||||
autoLoadImages: Boolean = true,
|
||||
options: List<Option> = emptyList(),
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
onDownVote: (() -> Unit)? = null,
|
||||
onSave: (() -> Unit)? = null,
|
||||
@ -63,9 +63,10 @@ fun CommentCard(
|
||||
endColor = MaterialTheme.colorScheme.background,
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier.onClick(rememberCallback {
|
||||
onClick?.invoke()
|
||||
}).padding(
|
||||
modifier = Modifier.onClick(
|
||||
onClick = onClick ?: {},
|
||||
onDoubleClick = onDoubleClick ?: {}
|
||||
).padding(
|
||||
start = if (hideIndent) 0.dp else (INDENT_AMOUNT * comment.depth).dp
|
||||
),
|
||||
) {
|
||||
@ -96,6 +97,7 @@ fun CommentCard(
|
||||
text = comment.text,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
PostCardFooter(
|
||||
|
@ -38,6 +38,7 @@ fun CommunityAndCreatorInfo(
|
||||
onOpenCommunity: ((CommunityModel) -> Unit)? = null,
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onToggleExpanded: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val communityName = community?.name.orEmpty()
|
||||
val communityIcon = community?.icon.orEmpty()
|
||||
@ -56,11 +57,12 @@ fun CommunityAndCreatorInfo(
|
||||
CustomImage(
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (community != null) {
|
||||
onOpenCommunity?.invoke(community)
|
||||
}
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
)
|
||||
.padding(Spacing.xxxs)
|
||||
.size(iconSize)
|
||||
@ -73,11 +75,12 @@ fun CommunityAndCreatorInfo(
|
||||
} else {
|
||||
PlaceholderImage(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (community != null) {
|
||||
onOpenCommunity?.invoke(community)
|
||||
}
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
size = IconSize.l,
|
||||
title = communityName,
|
||||
@ -88,11 +91,12 @@ fun CommunityAndCreatorInfo(
|
||||
CustomImage(
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (creator != null) {
|
||||
onOpenCreator?.invoke(creator)
|
||||
}
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
)
|
||||
.padding(Spacing.xxxs)
|
||||
.size(iconSize)
|
||||
@ -105,11 +109,12 @@ fun CommunityAndCreatorInfo(
|
||||
} else {
|
||||
PlaceholderImage(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (creator != null) {
|
||||
onOpenCreator?.invoke(creator)
|
||||
}
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
size = iconSize,
|
||||
title = creatorName,
|
||||
@ -123,9 +128,10 @@ fun CommunityAndCreatorInfo(
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenCommunity?.invoke(community)
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
text = buildString {
|
||||
append(communityName)
|
||||
@ -141,9 +147,10 @@ fun CommunityAndCreatorInfo(
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenCreator?.invoke(creator)
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
text = buildString {
|
||||
append(creatorName)
|
||||
@ -161,7 +168,7 @@ fun CommunityAndCreatorInfo(
|
||||
val expandedModifier = Modifier
|
||||
.padding(end = Spacing.xs)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onToggleExpanded?.invoke()
|
||||
},
|
||||
)
|
||||
|
@ -92,7 +92,7 @@ fun CommunityHeader(
|
||||
.size(IconSize.xxl)
|
||||
.clip(RoundedCornerShape(IconSize.xxl / 2))
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenImage?.invoke(communityIcon)
|
||||
},
|
||||
),
|
||||
|
@ -34,11 +34,13 @@ fun InboxCard(
|
||||
autoLoadImages: Boolean = true,
|
||||
separateUpAndDownVotes: Boolean = true,
|
||||
postLayout: PostLayout = PostLayout.Card,
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenPost: (PostModel) -> Unit,
|
||||
onOpenCreator: (UserModel) -> Unit,
|
||||
onOpenCommunity: (CommunityModel) -> Unit,
|
||||
onUpVote: ((CommentModel) -> Unit)? = null,
|
||||
onDownVote: ((CommentModel) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.let {
|
||||
@ -52,7 +54,7 @@ fun InboxCard(
|
||||
it.background(MaterialTheme.colorScheme.background)
|
||||
}
|
||||
}.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenPost(mention.post)
|
||||
},
|
||||
),
|
||||
@ -92,6 +94,7 @@ fun InboxCard(
|
||||
separateUpAndDownVotes = separateUpAndDownVotes,
|
||||
upVoted = mention.myVote > 0,
|
||||
downVoted = mention.myVote < 0,
|
||||
options = options,
|
||||
onOpenCommunity = onOpenCommunity,
|
||||
onOpenCreator = { user ->
|
||||
onOpenCreator(user)
|
||||
@ -102,6 +105,7 @@ fun InboxCard(
|
||||
onDownVote = {
|
||||
onDownVote?.invoke(mention.comment)
|
||||
},
|
||||
onOptionSelected = onOptionSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@ -11,6 +12,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowCircleDown
|
||||
import androidx.compose.material.icons.filled.ArrowCircleUp
|
||||
import androidx.compose.material.icons.filled.MoreHoriz
|
||||
import androidx.compose.material.icons.filled.Schedule
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@ -18,17 +20,23 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.ColorFilter
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.positionInParent
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
@ -36,6 +44,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.prettifyDate
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
|
||||
@ -50,6 +59,7 @@ fun InboxReplySubtitle(
|
||||
score: Int = 0,
|
||||
upvotes: Int = 0,
|
||||
downvotes: Int = 0,
|
||||
options: List<Option> = emptyList(),
|
||||
separateUpAndDownVotes: Boolean = false,
|
||||
upVoted: Boolean = false,
|
||||
downVoted: Boolean = false,
|
||||
@ -57,13 +67,17 @@ fun InboxReplySubtitle(
|
||||
onOpenCreator: ((UserModel) -> Unit)? = null,
|
||||
onUpVote: (() -> Unit)? = null,
|
||||
onDownVote: (() -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
) {
|
||||
val buttonModifier = Modifier.size(IconSize.m).padding(4.dp)
|
||||
val buttonModifier = Modifier.size(IconSize.m).padding(3.5.dp)
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
val downvoteColor by themeRepository.downvoteColor.collectAsState()
|
||||
val defaultUpvoteColor = MaterialTheme.colorScheme.primary
|
||||
val defaultDownVoteColor = MaterialTheme.colorScheme.tertiary
|
||||
var optionsExpanded by remember { mutableStateOf(false) }
|
||||
var optionsOffset by remember { mutableStateOf(Offset.Zero) }
|
||||
|
||||
Column(
|
||||
modifier = modifier,
|
||||
) {
|
||||
@ -83,7 +97,7 @@ fun InboxReplySubtitle(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (creator != null) {
|
||||
onOpenCreator?.invoke(creator)
|
||||
}
|
||||
@ -124,7 +138,7 @@ fun InboxReplySubtitle(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (community != null) {
|
||||
onOpenCommunity?.invoke(community)
|
||||
}
|
||||
@ -162,96 +176,143 @@ fun InboxReplySubtitle(
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = buttonModifier,
|
||||
imageVector = Icons.Default.Schedule,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Text(
|
||||
text = date?.prettifyDate() ?: "",
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onUpVote?.invoke()
|
||||
Box {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = buttonModifier,
|
||||
imageVector = Icons.Default.Schedule,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Text(
|
||||
text = date?.prettifyDate() ?: "",
|
||||
)
|
||||
if (options.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = buttonModifier
|
||||
.padding(top = Spacing.xxs)
|
||||
.onGloballyPositioned {
|
||||
optionsOffset = it.positionInParent()
|
||||
}
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = true
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.MoreHoriz,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
onUpVote?.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowCircleUp,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(
|
||||
color = if (upVoted) {
|
||||
upvoteColor ?: defaultUpvoteColor
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowCircleUp,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(
|
||||
color = if (upVoted) {
|
||||
upvoteColor ?: defaultUpvoteColor
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
if (separateUpAndDownVotes) {
|
||||
val upvoteText = upvotes.toString()
|
||||
append(upvoteText)
|
||||
if (upVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = upvoteColor ?: defaultUpvoteColor),
|
||||
start = 0,
|
||||
end = upvoteText.length
|
||||
)
|
||||
}
|
||||
append(" / ")
|
||||
val downvoteText = downvotes.toString()
|
||||
append(downvoteText)
|
||||
if (downVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(
|
||||
color = downvoteColor ?: defaultDownVoteColor
|
||||
),
|
||||
start = upvoteText.length + 3,
|
||||
end = upvoteText.length + 3 + downvoteText.length
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val text = score.toString()
|
||||
append(text)
|
||||
if (upVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = upvoteColor ?: defaultUpvoteColor),
|
||||
start = 0,
|
||||
end = text.length
|
||||
)
|
||||
} else if (downVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(
|
||||
color = downvoteColor ?: defaultDownVoteColor
|
||||
),
|
||||
start = 0,
|
||||
end = length
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = buildAnnotatedString {
|
||||
if (separateUpAndDownVotes) {
|
||||
val upvoteText = upvotes.toString()
|
||||
append(upvoteText)
|
||||
if (upVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = upvoteColor ?: defaultUpvoteColor),
|
||||
start = 0,
|
||||
end = upvoteText.length
|
||||
)
|
||||
}
|
||||
append(" / ")
|
||||
val downvoteText = downvotes.toString()
|
||||
append(downvoteText)
|
||||
if (downVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = downvoteColor ?: defaultDownVoteColor),
|
||||
start = upvoteText.length + 3,
|
||||
end = upvoteText.length + 3 + downvoteText.length
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val text = score.toString()
|
||||
append(text)
|
||||
if (upVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = upvoteColor ?: defaultUpvoteColor),
|
||||
start = 0,
|
||||
end = text.length
|
||||
)
|
||||
} else if (downVoted) {
|
||||
addStyle(
|
||||
style = SpanStyle(color = downvoteColor ?: defaultDownVoteColor),
|
||||
start = 0,
|
||||
end = length
|
||||
)
|
||||
}
|
||||
}
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
onDownVote?.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowCircleDown,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(
|
||||
color = if (downVoted) {
|
||||
downvoteColor ?: defaultDownVoteColor
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
CustomDropDown(
|
||||
expanded = optionsExpanded,
|
||||
onDismiss = {
|
||||
optionsExpanded = false
|
||||
},
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onDownVote?.invoke()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowCircleDown,
|
||||
contentDescription = null,
|
||||
colorFilter = ColorFilter.tint(
|
||||
color = if (downVoted) {
|
||||
downvoteColor ?: defaultDownVoteColor
|
||||
} else {
|
||||
MaterialTheme.colorScheme.onSurface
|
||||
},
|
||||
offset = DpOffset(
|
||||
x = optionsOffset.x.toLocalDp(),
|
||||
y = optionsOffset.y.toLocalDp(),
|
||||
),
|
||||
)
|
||||
) {
|
||||
options.forEach { option ->
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
),
|
||||
text = option.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,4 +17,6 @@ sealed class OptionId(val value: Int) {
|
||||
data object InfoInstance : OptionId(8)
|
||||
data object Block : OptionId(9)
|
||||
data object BlockInstance : OptionId(10)
|
||||
data object MarkRead : OptionId(11)
|
||||
data object MarkUnread : OptionId(12)
|
||||
}
|
@ -26,14 +26,17 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.toSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.CornerSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.web.WebViewScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.di.getSettingsRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.looksLikeAnImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalPixel
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
@ -63,6 +66,7 @@ fun PostCard(
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier.let {
|
||||
@ -74,7 +78,10 @@ fun PostCard(
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}.onClick(rememberCallback { onClick?.invoke() }),
|
||||
}.onClick(
|
||||
onClick = onClick ?: {},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
) {
|
||||
if (postLayout != PostLayout.Compact) {
|
||||
ExtendedPost(
|
||||
@ -101,6 +108,7 @@ fun PostCard(
|
||||
onImageClick = onImageClick,
|
||||
onOptionSelected = onOptionSelected,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
} else {
|
||||
CompactPost(
|
||||
@ -119,6 +127,7 @@ fun PostCard(
|
||||
onImageClick = onImageClick,
|
||||
onOptionSelected = onOptionSelected,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -142,6 +151,7 @@ private fun CompactPost(
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.background(MaterialTheme.colorScheme.background),
|
||||
@ -153,6 +163,7 @@ private fun CompactPost(
|
||||
onOpenCommunity = onOpenCommunity,
|
||||
onOpenCreator = onOpenCreator,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = Spacing.s),
|
||||
@ -165,6 +176,7 @@ private fun CompactPost(
|
||||
text = post.title,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
PostCardImage(
|
||||
@ -180,6 +192,7 @@ private fun CompactPost(
|
||||
},
|
||||
blurred = blurNsfw && post.nsfw,
|
||||
onImageClick = onImageClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
PostCardFooter(
|
||||
@ -225,6 +238,7 @@ private fun ExtendedPost(
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.background(backgroundColor),
|
||||
@ -237,6 +251,7 @@ private fun ExtendedPost(
|
||||
onOpenCommunity = onOpenCommunity,
|
||||
onOpenCreator = onOpenCreator,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
ScaledContent {
|
||||
PostCardTitle(
|
||||
@ -247,6 +262,7 @@ private fun ExtendedPost(
|
||||
text = post.title,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
|
||||
@ -269,6 +285,7 @@ private fun ExtendedPost(
|
||||
imageUrl = post.imageUrl,
|
||||
blurred = blurNsfw && post.nsfw,
|
||||
onImageClick = onImageClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
autoLoadImages = autoLoadImages,
|
||||
)
|
||||
if (showBody) {
|
||||
@ -290,6 +307,7 @@ private fun ExtendedPost(
|
||||
text = post.text,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
if (limitBodyHeight && textHeightPx >= maxHeightPx) {
|
||||
Box(
|
||||
@ -307,9 +325,25 @@ private fun ExtendedPost(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (post.url != post.imageUrl) {
|
||||
if (post.url != post.imageUrl && !post.url.isNullOrEmpty()) {
|
||||
val url = post.url.orEmpty()
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
|
||||
PostLinkBanner(
|
||||
modifier = Modifier.padding(vertical = Spacing.xs),
|
||||
modifier = Modifier
|
||||
.padding(vertical = Spacing.xs)
|
||||
.onClick(
|
||||
onClick = {
|
||||
if (settingsRepository.currentSettings.value.openUrlsInExternalBrowser) {
|
||||
uriHandler.openUri(url)
|
||||
} else {
|
||||
navigationCoordinator.pushScreen(WebViewScreen(url))
|
||||
}
|
||||
},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
url = post.url?.takeIf { !it.looksLikeAnImage }.orEmpty(),
|
||||
)
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ fun PostCardBody(
|
||||
text: String,
|
||||
autoLoadImages: Boolean = true,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
@ -27,17 +28,17 @@ fun PostCardBody(
|
||||
inlineImages = false,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onOpenUrl = { url ->
|
||||
handleUrl(
|
||||
navigationCoordinator.handleUrl(
|
||||
url = url,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator()
|
||||
)
|
||||
},
|
||||
onOpenImage = { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.pushScreen(ZoomableImageScreen(url))
|
||||
},
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ fun PostCardFooter(
|
||||
Image(
|
||||
modifier = buttonModifier.padding(1.dp)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onReply?.invoke()
|
||||
},
|
||||
),
|
||||
@ -110,11 +110,12 @@ fun PostCardFooter(
|
||||
if (options.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = buttonModifier
|
||||
.padding(top = Spacing.xxs)
|
||||
.onGloballyPositioned {
|
||||
optionsOffset = it.positionInParent()
|
||||
}
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = true
|
||||
},
|
||||
),
|
||||
@ -125,7 +126,7 @@ fun PostCardFooter(
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Image(
|
||||
modifier = buttonModifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSave?.invoke()
|
||||
},
|
||||
),
|
||||
@ -146,7 +147,7 @@ fun PostCardFooter(
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onUpVote?.invoke()
|
||||
},
|
||||
),
|
||||
@ -206,7 +207,7 @@ fun PostCardFooter(
|
||||
Image(
|
||||
modifier = buttonModifier
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onDownVote?.invoke()
|
||||
},
|
||||
),
|
||||
@ -238,7 +239,7 @@ fun PostCardFooter(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
|
@ -19,7 +19,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@ -33,6 +32,7 @@ fun PostCardImage(
|
||||
maxHeight: Dp = Dp.Unspecified,
|
||||
blurred: Boolean = false,
|
||||
onImageClick: ((String) -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
if (imageUrl.isNotEmpty()) {
|
||||
CustomImage(
|
||||
@ -40,9 +40,8 @@ fun PostCardImage(
|
||||
.heightIn(min = minHeight, max = maxHeight)
|
||||
.blur(radius = if (blurred) 60.dp else 0.dp)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onImageClick?.invoke(imageUrl)
|
||||
},
|
||||
onClick = { onImageClick?.invoke(imageUrl) },
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
),
|
||||
url = imageUrl,
|
||||
quality = FilterQuality.Low,
|
||||
|
@ -15,6 +15,7 @@ fun PostCardTitle(
|
||||
autoLoadImages: Boolean = true,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
@ -25,16 +26,16 @@ fun PostCardTitle(
|
||||
content = text,
|
||||
autoLoadImages = autoLoadImages,
|
||||
onOpenUrl = { url ->
|
||||
handleUrl(
|
||||
navigationCoordinator.handleUrl(
|
||||
url = url,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
onOpenImage = { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.pushScreen(ZoomableImageScreen(url))
|
||||
},
|
||||
onClick = onClick,
|
||||
onDoubleClick = onDoubleClick,
|
||||
)
|
||||
}
|
||||
|
@ -29,24 +29,12 @@ fun PostLinkBanner(
|
||||
modifier: Modifier = Modifier,
|
||||
url: String,
|
||||
) {
|
||||
val uriHandler = LocalUriHandler.current
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
|
||||
if (url.isNotEmpty()) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.tertiary.copy(alpha = 0.1f),
|
||||
shape = RoundedCornerShape(CornerSize.l),
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
if (settingsRepository.currentSettings.value.openUrlsInExternalBrowser) {
|
||||
uriHandler.openUri(url)
|
||||
} else {
|
||||
navigationCoordinator.getRootNavigator()?.push(WebViewScreen(url))
|
||||
}
|
||||
},
|
||||
).padding(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
|
@ -145,7 +145,7 @@ fun TextFormattingBar(
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectImage()
|
||||
},
|
||||
),
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.components
|
||||
|
||||
import androidx.compose.ui.platform.UriHandler
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation.NavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.userdetail.UserDetailScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.web.WebViewScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
|
||||
@ -39,18 +39,17 @@ fun getPostFromUrl(url: String?): Pair<PostModel, String>? {
|
||||
}
|
||||
}
|
||||
|
||||
fun handleUrl(
|
||||
fun NavigationCoordinator.handleUrl(
|
||||
url: String,
|
||||
openExternal: Boolean,
|
||||
uriHandler: UriHandler,
|
||||
navigator: Navigator? = null,
|
||||
) {
|
||||
val community = getCommunityFromUrl(url)
|
||||
val user = getUserFromUrl(url)
|
||||
|
||||
when {
|
||||
community != null && navigator != null -> {
|
||||
navigator.push(
|
||||
community != null -> {
|
||||
pushScreen(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = community.host
|
||||
@ -58,8 +57,8 @@ fun handleUrl(
|
||||
)
|
||||
}
|
||||
|
||||
user != null && navigator != null -> {
|
||||
navigator.push(
|
||||
user != null -> {
|
||||
pushScreen(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = user.host
|
||||
@ -71,11 +70,7 @@ fun handleUrl(
|
||||
uriHandler.openUri(url)
|
||||
}
|
||||
|
||||
navigator != null -> {
|
||||
navigator.push(WebViewScreen(url))
|
||||
}
|
||||
|
||||
else -> Unit
|
||||
else -> pushScreen(WebViewScreen(url))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ fun UserHeader(
|
||||
.size(IconSize.xxl)
|
||||
.clip(RoundedCornerShape(IconSize.xxl / 2))
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenImage?.invoke(userAvatar)
|
||||
},
|
||||
),
|
||||
|
@ -126,7 +126,7 @@ class CreateCommentScreen(
|
||||
CreateCommentMviModel.Effect.Success -> {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.CommentCreated)
|
||||
?.also { o -> o.invoke(Unit) }
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
|
||||
is CreateCommentMviModel.Effect.AddImageToText -> {
|
||||
|
@ -176,7 +176,7 @@ class CreatePostScreen(
|
||||
CreatePostMviModel.Effect.Success -> {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.PostCreated)
|
||||
?.also { o -> o.invoke(Unit) }
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
|
||||
is CreatePostMviModel.Effect.AddImageToBody -> {
|
||||
@ -190,7 +190,7 @@ class CreatePostScreen(
|
||||
DisposableEffect(key) {
|
||||
notificationCenter.addObserver(
|
||||
{
|
||||
(it as CommunityModel)?.also { community ->
|
||||
(it as? CommunityModel)?.also { community ->
|
||||
model.reduce(CreatePostMviModel.Intent.SetCommunity(community))
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
@ -357,7 +357,7 @@ class CreatePostScreen(
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
openImagePicker = true
|
||||
},
|
||||
),
|
||||
|
@ -190,7 +190,7 @@ object ModalDrawerContent : Tab {
|
||||
items(uiState.multiCommunities) { community ->
|
||||
MultiCommunityItem(
|
||||
modifier = Modifier.fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
scope.launch {
|
||||
coordinator.toggleDrawer()
|
||||
coordinator.sendEvent(
|
||||
@ -207,7 +207,7 @@ object ModalDrawerContent : Tab {
|
||||
items(uiState.communities) { community ->
|
||||
CommunityItem(
|
||||
modifier = Modifier.fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
scope.launch {
|
||||
coordinator.toggleDrawer()
|
||||
coordinator.sendEvent(
|
||||
@ -338,7 +338,7 @@ private fun DrawerHeader(
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpenChangeInstance?.invoke()
|
||||
},
|
||||
),
|
||||
@ -362,7 +362,7 @@ private fun DrawerShortcut(
|
||||
horizontal = Spacing.s,
|
||||
vertical = Spacing.xs,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelected?.invoke()
|
||||
},
|
||||
),
|
||||
@ -443,7 +443,7 @@ private fun ChangeInstanceDialog(
|
||||
if (instanceName.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onChangeInstanceName?.invoke("")
|
||||
},
|
||||
),
|
||||
|
@ -81,8 +81,8 @@ class ZoomableImageScreen(
|
||||
navigationIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -93,7 +93,7 @@ class ZoomableImageScreen(
|
||||
actions = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(ZoomableImageMviModel.Intent.SaveToGallery(url))
|
||||
},
|
||||
),
|
||||
@ -104,7 +104,7 @@ class ZoomableImageScreen(
|
||||
Spacer(Modifier.width(Spacing.s))
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(ZoomableImageMviModel.Intent.Share(url))
|
||||
},
|
||||
),
|
||||
|
@ -114,8 +114,8 @@ class InstanceInfoScreen(
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -145,7 +145,7 @@ class InstanceInfoScreen(
|
||||
}
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
values = listOf(
|
||||
SortType.Active,
|
||||
@ -158,7 +158,7 @@ class InstanceInfoScreen(
|
||||
),
|
||||
expandTop = true,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -232,8 +232,8 @@ class InstanceInfoScreen(
|
||||
items(uiState.communities) {
|
||||
CommunityItem(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(
|
||||
community = it,
|
||||
otherInstance = instanceName,
|
||||
|
@ -95,13 +95,13 @@ class ColorBottomSheet : Screen {
|
||||
horizontal = Spacing.s,
|
||||
vertical = Spacing.s,
|
||||
).fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (!isChooseCustom) {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.ChangeColor)
|
||||
?.also {
|
||||
it.invoke(value.first ?: Unit)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
} else {
|
||||
customPickerDialogOpened = true
|
||||
}
|
||||
@ -149,7 +149,7 @@ class ColorBottomSheet : Screen {
|
||||
?.also {
|
||||
it.invoke(color)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -73,13 +73,13 @@ class DurationBottomSheet(
|
||||
horizontal = Spacing.s,
|
||||
vertical = Spacing.s,
|
||||
).fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.ChangeZombieInterval
|
||||
)?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -74,14 +74,14 @@ class FontFamilyBottomSheet(
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.ChangeFontFamily
|
||||
)
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -75,11 +75,11 @@ class FontScaleBottomSheet(
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(contract)?.also {
|
||||
it.invoke(value.scaleFactor)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -61,12 +61,12 @@ class InboxTypeSheet : Screen {
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.ChangeInboxType)
|
||||
?.also {
|
||||
it.invoke(true)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
@ -83,12 +83,12 @@ class InboxTypeSheet : Screen {
|
||||
horizontal = Spacing.s,
|
||||
vertical = Spacing.m,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.ChangeInboxType)
|
||||
?.also {
|
||||
it.invoke(false)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -75,14 +75,14 @@ class LanguageBottomSheet : Screen {
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.ChangeLanguage
|
||||
)
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -77,13 +77,13 @@ class ListingTypeBottomSheet(
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getAllObservers(
|
||||
NotificationCenterContractKeys.ChangeFeedType
|
||||
).forEach {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -67,12 +67,12 @@ class PostLayoutBottomSheet : Screen {
|
||||
horizontal = Spacing.s,
|
||||
vertical = Spacing.m,
|
||||
).fillMaxWidth().onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.ChangePostLayout)
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -76,7 +76,7 @@ class SliderBottomSheet(
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
) {
|
||||
Text(text = stringResource(MR.strings.button_confirm))
|
||||
|
@ -109,14 +109,14 @@ internal class SortBottomSheetMain(
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (value == SortType.Top.Generic && expandTop) {
|
||||
navigator.push(SortBottomSheetTop(contract = contract))
|
||||
} else {
|
||||
notificationCenter.getAllObservers(contract).forEach {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
},
|
||||
),
|
||||
@ -172,7 +172,7 @@ internal class SortBottomSheetTop(
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
navigator.pop()
|
||||
},
|
||||
),
|
||||
@ -199,13 +199,13 @@ internal class SortBottomSheetTop(
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getAllObservers(
|
||||
contract,
|
||||
).forEach {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -75,12 +75,12 @@ class ThemeBottomSheet : Screen {
|
||||
)
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(NotificationCenterContractKeys.ChangeTheme)
|
||||
?.also {
|
||||
it.invoke(value)
|
||||
}
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
},
|
||||
),
|
||||
) {
|
||||
|
@ -1,20 +1,31 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation
|
||||
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
private const val NAVIGATION_DELAY = 250L
|
||||
private const val BOTTOM_NAVIGATION_DELAY = 150L
|
||||
private const val DEEP_LINK_DELAY = 500L
|
||||
|
||||
internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
|
||||
override val onDoubleTabSelection = MutableSharedFlow<Tab>()
|
||||
override val deepLinkUrl = MutableSharedFlow<String>()
|
||||
override val inboxUnread = MutableStateFlow(0)
|
||||
override val canPop: Boolean
|
||||
get() = navigator?.canPop == true
|
||||
|
||||
private var connection: NestedScrollConnection? = null
|
||||
private var navigator: Navigator? = null
|
||||
@ -22,14 +33,12 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
private var currentTab: Tab? = null
|
||||
private val scope = CoroutineScope(SupervisorJob())
|
||||
private var canGoBackCallback: (() -> Boolean)? = null
|
||||
override val inboxUnread = MutableStateFlow(0)
|
||||
private var job: Job? = null
|
||||
|
||||
override fun setRootNavigator(value: Navigator?) {
|
||||
navigator = value
|
||||
}
|
||||
|
||||
override fun getRootNavigator(): Navigator? = navigator
|
||||
|
||||
override fun setBottomBarScrollConnection(value: NestedScrollConnection?) {
|
||||
connection = value
|
||||
}
|
||||
@ -48,8 +57,11 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
|
||||
override fun submitDeeplink(url: String) {
|
||||
scope.launch {
|
||||
delay(500)
|
||||
deepLinkUrl.emit(url)
|
||||
delay(DEEP_LINK_DELAY)
|
||||
runCatching {
|
||||
ensureActive()
|
||||
deepLinkUrl.emit(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,7 +79,47 @@ internal class DefaultNavigationCoordinator : NavigationCoordinator {
|
||||
bottomNavigator = value
|
||||
}
|
||||
|
||||
override fun getBottomNavigator(): BottomSheetNavigator? {
|
||||
return bottomNavigator
|
||||
override fun showBottomSheet(screen: Screen) {
|
||||
job?.cancel()
|
||||
job = scope.launch {
|
||||
delay(BOTTOM_NAVIGATION_DELAY)
|
||||
runCatching {
|
||||
ensureActive()
|
||||
bottomNavigator?.show(screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun pushScreen(screen: Screen) {
|
||||
job?.cancel()
|
||||
job = scope.launch {
|
||||
delay(NAVIGATION_DELAY)
|
||||
runCatching {
|
||||
ensureActive()
|
||||
navigator?.push(screen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun hideBottomSheet() {
|
||||
job?.cancel()
|
||||
job = scope.launch {
|
||||
delay(BOTTOM_NAVIGATION_DELAY)
|
||||
runCatching {
|
||||
ensureActive()
|
||||
bottomNavigator?.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun popScreen() {
|
||||
job?.cancel()
|
||||
job = scope.launch {
|
||||
delay(NAVIGATION_DELAY)
|
||||
runCatching {
|
||||
ensureActive()
|
||||
navigator?.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.core.commonui.navigation
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import cafe.adriel.voyager.core.screen.Screen
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.navigator.bottomSheet.BottomSheetNavigator
|
||||
import cafe.adriel.voyager.navigator.tab.Tab
|
||||
@ -14,26 +15,19 @@ interface NavigationCoordinator {
|
||||
val onDoubleTabSelection: Flow<Tab>
|
||||
val inboxUnread: StateFlow<Int>
|
||||
val deepLinkUrl: Flow<String?>
|
||||
val canPop: Boolean
|
||||
|
||||
fun setCurrentSection(tab: Tab)
|
||||
|
||||
fun submitDeeplink(url: String)
|
||||
|
||||
fun setRootNavigator(value: Navigator?)
|
||||
|
||||
fun setCanGoBackCallback(value: (() -> Boolean)?)
|
||||
|
||||
fun getCanGoBackCallback(): (() -> Boolean)?
|
||||
|
||||
fun getRootNavigator(): Navigator?
|
||||
|
||||
fun setBottomBarScrollConnection(value: NestedScrollConnection?)
|
||||
|
||||
fun getBottomBarScrollConnection(): NestedScrollConnection?
|
||||
|
||||
fun setInboxUnread(count: Int)
|
||||
|
||||
fun setBottomNavigator(value: BottomSheetNavigator?)
|
||||
|
||||
fun getBottomNavigator(): BottomSheetNavigator?
|
||||
fun showBottomSheet(screen: Screen)
|
||||
fun hideBottomSheet()
|
||||
fun pushScreen(screen: Screen)
|
||||
fun popScreen()
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ interface PostDetailMviModel :
|
||||
val comments: List<CommentModel> = emptyList(),
|
||||
val currentUserId: Int? = null,
|
||||
val swipeActionsEnabled: Boolean = true,
|
||||
val doubleTapActionEnabled: Boolean = true,
|
||||
val postLayout: PostLayout = PostLayout.Card,
|
||||
val fullHeightImages: Boolean = true,
|
||||
val separateUpAndDownVotes: Boolean = false,
|
||||
|
@ -230,7 +230,7 @@ class PostDetailScreen(
|
||||
model.effects.onEach { evt ->
|
||||
when (evt) {
|
||||
PostDetailMviModel.Effect.Close -> {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
navigationCoordinator.popScreen()
|
||||
}
|
||||
|
||||
is PostDetailMviModel.Effect.ScrollToComment -> {
|
||||
@ -263,7 +263,7 @@ class PostDetailScreen(
|
||||
actions = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
values = listOf(
|
||||
SortType.Hot,
|
||||
@ -273,7 +273,7 @@ class PostDetailScreen(
|
||||
SortType.Controversial,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -282,12 +282,11 @@ class PostDetailScreen(
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
if (navigationCoordinator.canPop) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -328,7 +327,7 @@ class PostDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = uiState.post,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -365,12 +364,12 @@ class PostDetailScreen(
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = false,
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community = community)
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user = user)
|
||||
)
|
||||
},
|
||||
@ -405,7 +404,7 @@ class PostDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = uiState.post,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
@ -455,19 +454,19 @@ class PostDetailScreen(
|
||||
OptionId.Delete -> model.reduce(PostDetailMviModel.Intent.DeletePost)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(editedPost = uiState.post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(postId = uiState.post.id)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(crossPost = uiState.post)
|
||||
)
|
||||
}
|
||||
@ -482,7 +481,7 @@ class PostDetailScreen(
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -523,15 +522,14 @@ class PostDetailScreen(
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val post = PostModel(
|
||||
id = crossPost.id,
|
||||
community = community,
|
||||
)
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
PostDetailScreen(post)
|
||||
)
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(post)
|
||||
)
|
||||
},
|
||||
),
|
||||
text = string,
|
||||
@ -639,6 +637,18 @@ class PostDetailScreen(
|
||||
)
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostDetailMviModel.Intent.UpVoteComment(
|
||||
commentId = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
if (uiState.isLogged && !isOnOtherInstance) {
|
||||
model.reduce(
|
||||
@ -675,32 +685,31 @@ class PostDetailScreen(
|
||||
originalPost = uiState.post,
|
||||
originalComment = comment,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
screen
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
val user = comment.creator
|
||||
if (user != null) {
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstanceName,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstanceName,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs {
|
||||
val community = comment.community
|
||||
if (community != null) {
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = otherInstanceName,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(
|
||||
community = community,
|
||||
otherInstance = otherInstanceName,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
options = buildList {
|
||||
@ -742,21 +751,19 @@ class PostDetailScreen(
|
||||
)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
@ -815,14 +822,13 @@ class PostDetailScreen(
|
||||
originalPost = uiState.post,
|
||||
originalComment = comment,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
val user = comment.creator
|
||||
if (user != null) {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(
|
||||
user = user,
|
||||
otherInstance = otherInstanceName,
|
||||
@ -867,21 +873,19 @@ class PostDetailScreen(
|
||||
)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateCommentScreen(
|
||||
editedComment = comment,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
|
@ -70,6 +70,7 @@ class PostDetailViewModel(
|
||||
mvi.updateState {
|
||||
it.copy(
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
sortType = settings.defaultCommentSortType.toSortType(),
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
|
@ -73,7 +73,7 @@ class CreateReportScreen(
|
||||
}
|
||||
|
||||
CreateReportMviModel.Effect.Success -> {
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
@ -138,7 +138,7 @@ class SavedItemsScreen : Screen {
|
||||
actions = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
values = listOf(
|
||||
SortType.Hot,
|
||||
@ -146,7 +146,7 @@ class SavedItemsScreen : Screen {
|
||||
SortType.Old,
|
||||
),
|
||||
)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigatorCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -157,8 +157,8 @@ class SavedItemsScreen : Screen {
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigatorCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -250,19 +250,18 @@ class SavedItemsScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
navigatorCoordinator.pushScreen(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = { community ->
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
navigatorCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = { u ->
|
||||
if (u.id != uiState.user?.id) {
|
||||
navigatorCoordinator.getRootNavigator()
|
||||
?.push(UserDetailScreen(u))
|
||||
navigatorCoordinator.pushScreen(UserDetailScreen(u))
|
||||
}
|
||||
},
|
||||
onUpVote = {
|
||||
@ -293,10 +292,10 @@ class SavedItemsScreen : Screen {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigatorCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
onImageClick = { url ->
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
navigatorCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -323,7 +322,7 @@ class SavedItemsScreen : Screen {
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
OptionId.Report -> {
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
navigatorCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
@ -373,7 +372,7 @@ class SavedItemsScreen : Screen {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
hideIndent = true,
|
||||
onClick = {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
navigatorCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
@ -409,7 +408,7 @@ class SavedItemsScreen : Screen {
|
||||
originalPost = PostModel(id = comment.postId),
|
||||
originalComment = comment,
|
||||
)
|
||||
navigatorCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigatorCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
options = buildList {
|
||||
add(
|
||||
@ -428,7 +427,7 @@ class SavedItemsScreen : Screen {
|
||||
onOptionSelected = { optionIndex ->
|
||||
when (optionIndex) {
|
||||
OptionId.Report -> {
|
||||
navigatorCoordinator.getBottomNavigator()?.show(
|
||||
navigatorCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
|
@ -97,7 +97,7 @@ class SelectCommunityDialog : Screen {
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(SelectCommunityMviModel.Intent.SetSearch(""))
|
||||
}
|
||||
@ -127,16 +127,18 @@ class SelectCommunityDialog : Screen {
|
||||
CommunityItem(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.onClick(rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.SelectCommunity
|
||||
)
|
||||
?.invoke(community)
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.CloseDialog
|
||||
)
|
||||
?.invoke(Unit)
|
||||
}),
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.SelectCommunity
|
||||
)
|
||||
?.invoke(community)
|
||||
notificationCenter.getObserver(
|
||||
NotificationCenterContractKeys.CloseDialog
|
||||
)
|
||||
?.invoke(Unit)
|
||||
},
|
||||
),
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
community = community,
|
||||
)
|
||||
|
@ -46,6 +46,7 @@ interface UserDetailMviModel :
|
||||
val user: UserModel = UserModel(),
|
||||
val blurNsfw: Boolean = true,
|
||||
val swipeActionsEnabled: Boolean = true,
|
||||
val doubleTapActionEnabled: Boolean = true,
|
||||
val postLayout: PostLayout = PostLayout.Card,
|
||||
val fullHeightImages: Boolean = true,
|
||||
val separateUpAndDownVotes: Boolean = false,
|
||||
|
@ -227,11 +227,11 @@ class UserDetailScreen(
|
||||
// sort button
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = uiState.sortType.toIcon(),
|
||||
@ -257,7 +257,7 @@ class UserDetailScreen(
|
||||
modifier = Modifier.onGloballyPositioned {
|
||||
optionsOffset = it.positionInParent()
|
||||
}.padding(start = Spacing.s).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = true
|
||||
},
|
||||
),
|
||||
@ -281,7 +281,7 @@ class UserDetailScreen(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = false
|
||||
when (option.id) {
|
||||
OptionId.BlockInstance -> model.reduce(
|
||||
@ -303,12 +303,11 @@ class UserDetailScreen(
|
||||
}
|
||||
},
|
||||
navigationIcon = {
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
if (navigator?.canPop == true) {
|
||||
if (navigationCoordinator.canPop) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigator.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -348,7 +347,7 @@ class UserDetailScreen(
|
||||
text = stringResource(MR.strings.action_chat),
|
||||
onSelected = rememberCallback {
|
||||
val screen = InboxChatScreen(otherUserId = user.id)
|
||||
navigationCoordinator.getRootNavigator()?.push(screen)
|
||||
navigationCoordinator.pushScreen(screen)
|
||||
},
|
||||
)
|
||||
}
|
||||
@ -391,8 +390,7 @@ class UserDetailScreen(
|
||||
user = uiState.user,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.pushScreen(ZoomableImageScreen(url))
|
||||
},
|
||||
)
|
||||
SectionSelector(
|
||||
@ -486,8 +484,21 @@ class UserDetailScreen(
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(PostDetailScreen(post = post))
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(post = post),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onUpVote = if (!uiState.isLogged || isOnOtherInstance) {
|
||||
null
|
||||
@ -526,8 +537,9 @@ class UserDetailScreen(
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(CommunityDetailScreen(community))
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onReply = if (!uiState.isLogged || isOnOtherInstance) {
|
||||
null
|
||||
@ -536,12 +548,11 @@ class UserDetailScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -576,19 +587,17 @@ class UserDetailScreen(
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
@ -689,13 +698,25 @@ class UserDetailScreen(
|
||||
hideAuthor = true,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
)
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
UserDetailMviModel.Intent.UpVoteComment(
|
||||
id = comment.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onSave = if (!uiState.isLogged || isOnOtherInstance) {
|
||||
null
|
||||
} else {
|
||||
@ -740,13 +761,15 @@ class UserDetailScreen(
|
||||
originalPost = PostModel(id = comment.postId),
|
||||
originalComment = comment,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(CommunityDetailScreen(community))
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(
|
||||
community
|
||||
)
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(
|
||||
@ -767,12 +790,11 @@ class UserDetailScreen(
|
||||
onOptionSelected = rememberCallbackArgs { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
commentId = comment.id
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
|
@ -79,6 +79,7 @@ class UserDetailViewModel(
|
||||
it.copy(
|
||||
blurNsfw = settings.blurNsfw,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
sortType = settings.defaultPostSortType.toSortType(),
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
|
@ -35,7 +35,7 @@ class WebViewScreen(
|
||||
override fun Content() {
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
|
||||
var shareHelper = remember { getShareHelper() }
|
||||
val shareHelper = remember { getShareHelper() }
|
||||
val drawerCoordinator = remember { getDrawerCoordinator() }
|
||||
|
||||
DisposableEffect(key) {
|
||||
@ -53,8 +53,8 @@ class WebViewScreen(
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -65,7 +65,7 @@ class WebViewScreen(
|
||||
actions = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
shareHelper.share(url, "text/plain")
|
||||
},
|
||||
),
|
||||
@ -80,7 +80,6 @@ class WebViewScreen(
|
||||
Box(
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
) {
|
||||
val navigationCoordinator = remember { getNavigationCoordinator() }
|
||||
val webNavigator = rememberWebViewNavigator()
|
||||
|
||||
DisposableEffect(key) {
|
||||
|
@ -46,6 +46,7 @@ kotlin {
|
||||
|
||||
api(libs.markdown)
|
||||
implementation(projects.coreCommonui.components)
|
||||
implementation(projects.coreUtils)
|
||||
implementation(projects.resources)
|
||||
}
|
||||
}
|
||||
|
@ -3,11 +3,11 @@ package com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose
|
||||
import android.content.Context
|
||||
import android.graphics.Typeface
|
||||
import android.util.TypedValue
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
@ -30,6 +30,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownColo
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownPadding
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownTypography
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.ReferenceLinkHandlerImpl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.DateTime
|
||||
import io.noties.markwon.image.AsyncDrawableSpan
|
||||
import org.intellij.markdown.flavours.MarkdownFlavourDescriptor
|
||||
|
||||
@ -50,6 +52,7 @@ actual fun CustomMarkdown(
|
||||
autoLoadImages: Boolean,
|
||||
onOpenImage: ((String) -> Unit)?,
|
||||
onClick: (() -> Unit)?,
|
||||
onDoubleClick: (() -> Unit)?,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalReferenceLinkHandler provides ReferenceLinkHandlerImpl(),
|
||||
@ -64,10 +67,10 @@ actual fun CustomMarkdown(
|
||||
)
|
||||
}
|
||||
BoxWithConstraints(
|
||||
modifier = modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) { onClick?.invoke() }
|
||||
modifier = modifier.onClick(
|
||||
onClick = onClick ?: {},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
)
|
||||
) {
|
||||
val style = LocalMarkdownTypography.current.text
|
||||
val fontScale = LocalDensity.current.fontScale * 1.25f
|
||||
@ -93,9 +96,35 @@ actual fun CustomMarkdown(
|
||||
typeface = typeface,
|
||||
fontSize = style.fontSize * fontScale,
|
||||
).apply {
|
||||
setOnClickListener {
|
||||
onClick?.invoke()
|
||||
}
|
||||
val gestureDetector =
|
||||
GestureDetector(
|
||||
ctx,
|
||||
object : GestureDetector.SimpleOnGestureListener() {
|
||||
|
||||
private var lastClickTime = 0L
|
||||
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
val currentTime = DateTime.epochMillis()
|
||||
if ((currentTime - lastClickTime) < 300) return false
|
||||
lastClickTime = currentTime
|
||||
onClick?.invoke()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDoubleTap(e: MotionEvent): Boolean {
|
||||
val currentTime = DateTime.epochMillis()
|
||||
if ((currentTime - lastClickTime) < 300) return false
|
||||
lastClickTime = currentTime
|
||||
onDoubleClick?.invoke()
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDown(e: MotionEvent): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
)
|
||||
setOnTouchListener { _, evt -> gestureDetector.onTouchEvent(evt) }
|
||||
}
|
||||
},
|
||||
update = { textView ->
|
||||
|
@ -38,4 +38,5 @@ expect fun CustomMarkdown(
|
||||
autoLoadImages: Boolean = true,
|
||||
onOpenImage: ((String) -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
onDoubleClick: (() -> Unit)? = null,
|
||||
)
|
@ -4,9 +4,7 @@ import androidx.compose.animation.core.InfiniteRepeatableSpec
|
||||
import androidx.compose.animation.core.animateFloat
|
||||
import androidx.compose.animation.core.rememberInfiniteTransition
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.detectTapGestures
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
@ -40,6 +38,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose.LocalMarkd
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose.LocalReferenceLinkHandler
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.utils.TAG_IMAGE_URL
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.utils.TAG_URL
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@ -121,12 +120,9 @@ internal fun MarkdownText(
|
||||
CustomImage(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) {
|
||||
onOpenImage?.invoke(imageUrl)
|
||||
},
|
||||
.onClick(
|
||||
onClick = { onOpenImage?.invoke(imageUrl) },
|
||||
),
|
||||
url = link,
|
||||
autoload = autoLoadImages,
|
||||
quality = FilterQuality.Low,
|
||||
@ -175,12 +171,10 @@ internal fun MarkdownText(
|
||||
// TODO: improve fixed values
|
||||
.heightIn(min = 200.dp, max = Dp.Unspecified)
|
||||
.clip(RoundedCornerShape(20.dp))
|
||||
.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) {
|
||||
onOpenImage?.invoke(imageUrl)
|
||||
},
|
||||
.onClick(
|
||||
onClick = { onOpenImage?.invoke(imageUrl) },
|
||||
onDoubleClick = {},
|
||||
),
|
||||
url = imageUrl,
|
||||
autoload = autoLoadImages,
|
||||
quality = FilterQuality.Low,
|
||||
|
@ -44,3 +44,4 @@ internal fun List<ASTNode>.innerList(): List<ASTNode> = this.subList(1, this.siz
|
||||
internal fun List<ASTNode>.filterNonListTypes(): List<ASTNode> = this.filter { n ->
|
||||
n.type != MarkdownElementTypes.ORDERED_LIST && n.type != MarkdownElementTypes.UNORDERED_LIST && n.type != MarkdownTokenTypes.EOL
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,10 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose.elements.MarkdownBlockQuote
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.compose.elements.MarkdownBulletList
|
||||
@ -22,6 +19,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownColo
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownPadding
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.MarkdownTypography
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.markdown.model.ReferenceLinkHandlerImpl
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import org.intellij.markdown.MarkdownElementTypes
|
||||
import org.intellij.markdown.MarkdownElementTypes.ATX_1
|
||||
import org.intellij.markdown.MarkdownElementTypes.ATX_2
|
||||
@ -62,6 +60,7 @@ actual fun CustomMarkdown(
|
||||
autoLoadImages: Boolean,
|
||||
onOpenImage: ((String) -> Unit)?,
|
||||
onClick: (() -> Unit)?,
|
||||
onDoubleClick: (() -> Unit)?,
|
||||
) {
|
||||
val matches = Regex("::: spoiler (?<title>.*?)\\n(?<content>.*?)\\n:::\\n").findAll(content)
|
||||
val mangledContent = buildString {
|
||||
@ -97,10 +96,12 @@ actual fun CustomMarkdown(
|
||||
LocalMarkdownColors provides colors,
|
||||
LocalMarkdownTypography provides typography,
|
||||
) {
|
||||
Column(modifier.clickable(
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
indication = null
|
||||
) { onClick?.invoke() }) {
|
||||
Column(
|
||||
modifier = modifier.onClick(
|
||||
onClick = onClick ?: {},
|
||||
onDoubleClick = onDoubleClick ?: {},
|
||||
)
|
||||
) {
|
||||
val parsedTree = MarkdownParser(flavour).buildMarkdownTreeFromString(mangledContent)
|
||||
parsedTree.children.forEach { node ->
|
||||
if (!node.handleElement(
|
||||
|
@ -20,6 +20,7 @@ data class SettingsModel(
|
||||
val dynamicColors: Boolean = false,
|
||||
val openUrlsInExternalBrowser: Boolean = false,
|
||||
val enableSwipeActions: Boolean = true,
|
||||
val enableDoubleTapAction: Boolean = false,
|
||||
val customSeedColor: Int? = null,
|
||||
val upvoteColor: Int? = null,
|
||||
val downvoteColor: Int? = null,
|
||||
|
@ -25,6 +25,7 @@ private object KeyStoreKeys {
|
||||
const val DynamicColors = "dynamicColors"
|
||||
const val OpenUrlsInExternalBrowser = "openUrlsInExternalBrowser"
|
||||
const val EnableSwipeActions = "enableSwipeActions"
|
||||
const val EnableDoubleTapAction = "enableDoubleTapAction"
|
||||
const val CustomSeedColor = "customPrimaryColor"
|
||||
const val PostLayout = "postLayout"
|
||||
const val SeparateUpAndDownVotes = "separateUpAndDownVotes"
|
||||
@ -64,6 +65,7 @@ internal class DefaultSettingsRepository(
|
||||
dynamicColors = if (settings.dynamicColors) 1L else 0L,
|
||||
openUrlsInExternalBrowser = if (settings.openUrlsInExternalBrowser) 1L else 0L,
|
||||
enableSwipeActions = if (settings.enableSwipeActions) 1L else 0L,
|
||||
enableDoubleTapAction = if (settings.enableDoubleTapAction) 1L else 0L,
|
||||
customSeedColor = settings.customSeedColor?.toLong(),
|
||||
account_id = accountId,
|
||||
postLayout = settings.postLayout.toLong(),
|
||||
@ -100,6 +102,7 @@ internal class DefaultSettingsRepository(
|
||||
dynamicColors = keyStore[KeyStoreKeys.DynamicColors, false],
|
||||
openUrlsInExternalBrowser = keyStore[KeyStoreKeys.OpenUrlsInExternalBrowser, false],
|
||||
enableSwipeActions = keyStore[KeyStoreKeys.EnableSwipeActions, true],
|
||||
enableDoubleTapAction = keyStore[KeyStoreKeys.EnableDoubleTapAction, false],
|
||||
customSeedColor = if (!keyStore.containsKey(KeyStoreKeys.CustomSeedColor)) null else keyStore[KeyStoreKeys.CustomSeedColor, 0],
|
||||
postLayout = keyStore[KeyStoreKeys.PostLayout, 0],
|
||||
separateUpAndDownVotes = keyStore[KeyStoreKeys.SeparateUpAndDownVotes, false],
|
||||
@ -148,6 +151,7 @@ internal class DefaultSettingsRepository(
|
||||
value = settings.openUrlsInExternalBrowser
|
||||
)
|
||||
keyStore.save(KeyStoreKeys.EnableSwipeActions, settings.enableSwipeActions)
|
||||
keyStore.save(KeyStoreKeys.EnableDoubleTapAction, settings.enableDoubleTapAction)
|
||||
if (settings.customSeedColor != null) {
|
||||
keyStore.save(KeyStoreKeys.CustomSeedColor, settings.customSeedColor)
|
||||
} else {
|
||||
@ -196,6 +200,7 @@ internal class DefaultSettingsRepository(
|
||||
dynamicColors = if (settings.dynamicColors) 1L else 0L,
|
||||
openUrlsInExternalBrowser = if (settings.openUrlsInExternalBrowser) 1L else 0L,
|
||||
enableSwipeActions = if (settings.enableSwipeActions) 1L else 0L,
|
||||
enableDoubleTapAction = if (settings.enableDoubleTapAction) 1L else 0L,
|
||||
customSeedColor = settings.customSeedColor?.toLong(),
|
||||
postLayout = settings.postLayout.toLong(),
|
||||
separateUpAndDownVotes = if (settings.separateUpAndDownVotes) 1L else 0L,
|
||||
@ -233,6 +238,7 @@ private fun GetBy.toModel() = SettingsModel(
|
||||
dynamicColors = dynamicColors != 0L,
|
||||
openUrlsInExternalBrowser = openUrlsInExternalBrowser != 0L,
|
||||
enableSwipeActions = enableSwipeActions != 0L,
|
||||
enableDoubleTapAction = enableDoubleTapAction != 0L,
|
||||
customSeedColor = customSeedColor?.toInt(),
|
||||
postLayout = postLayout.toInt(),
|
||||
separateUpAndDownVotes = separateUpAndDownVotes != 0L,
|
||||
|
@ -14,6 +14,7 @@ CREATE TABLE SettingsEntity (
|
||||
dynamicColors INTEGER NOT NULL DEFAULT 0,
|
||||
openUrlsInExternalBrowser INTEGER NOT NULL DEFAULT 0,
|
||||
enableSwipeActions INTEGER NOT NULL DEFAULT 1,
|
||||
enableDoubleTapAction INTEGER NOT NULL DEFAULT 1,
|
||||
customSeedColor INTEGER DEFAULT NULL,
|
||||
postLayout INTEGER NOT NULL DEFAULT 0,
|
||||
separateUpAndDownVotes INTEGER NOT NULL DEFAULT 0,
|
||||
@ -46,6 +47,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
dynamicColors,
|
||||
openUrlsInExternalBrowser,
|
||||
enableSwipeActions,
|
||||
enableDoubleTapAction,
|
||||
customSeedColor,
|
||||
postLayout,
|
||||
separateUpAndDownVotes,
|
||||
@ -84,6 +86,7 @@ INSERT OR IGNORE INTO SettingsEntity (
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?,
|
||||
?
|
||||
);
|
||||
|
||||
@ -103,6 +106,7 @@ SET theme = ?,
|
||||
dynamicColors = ?,
|
||||
openUrlsInExternalBrowser = ?,
|
||||
enableSwipeActions = ?,
|
||||
enableDoubleTapAction = ?,
|
||||
customSeedColor = ?,
|
||||
postLayout = ?,
|
||||
separateUpAndDownVotes = ?,
|
||||
@ -133,6 +137,7 @@ SELECT
|
||||
dynamicColors,
|
||||
openUrlsInExternalBrowser,
|
||||
enableSwipeActions,
|
||||
enableDoubleTapAction,
|
||||
customSeedColor,
|
||||
postLayout,
|
||||
separateUpAndDownVotes,
|
||||
|
@ -0,0 +1,2 @@
|
||||
ALTER TABLE SettingsEntity
|
||||
ADD COLUMN enableDoubleTapAction INTEGER NOT NULL DEFAULT 1;
|
@ -1,16 +1,37 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.core.utils.compose
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.DateTime
|
||||
|
||||
fun Modifier.onClick(onClick: () -> Unit): Modifier = composed {
|
||||
clickable(
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
fun Modifier.onClick(
|
||||
debounceInterval: Long = 300,
|
||||
onClick: () -> Unit = {},
|
||||
onDoubleClick: () -> Unit = {},
|
||||
): Modifier = composed {
|
||||
var lastClickTime by remember { mutableStateOf(0L) }
|
||||
combinedClickable(
|
||||
indication = null,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
onClick()
|
||||
}
|
||||
onClick = {
|
||||
val currentTime = DateTime.epochMillis()
|
||||
if ((currentTime - lastClickTime) < debounceInterval) return@combinedClickable
|
||||
lastClickTime = currentTime
|
||||
onClick()
|
||||
},
|
||||
onDoubleClick = {
|
||||
val currentTime = DateTime.epochMillis()
|
||||
if ((currentTime - lastClickTime) < debounceInterval) return@combinedClickable
|
||||
lastClickTime = currentTime
|
||||
onDoubleClick()
|
||||
},
|
||||
)
|
||||
}
|
@ -35,6 +35,6 @@ val PostModel.shareUrl: String
|
||||
}
|
||||
|
||||
val PostModel.imageUrl: String
|
||||
get() = thumbnailUrl?.takeIf { it.isNotEmpty() } ?: run {
|
||||
url?.takeIf { it.looksLikeAnImage }
|
||||
get() = url?.takeIf { it.looksLikeAnImage }?.takeIf { it.isNotEmpty() } ?: run {
|
||||
thumbnailUrl
|
||||
}.orEmpty()
|
||||
|
@ -44,6 +44,7 @@ interface PostListMviModel :
|
||||
val blurNsfw: Boolean = true,
|
||||
val currentUserId: Int? = null,
|
||||
val swipeActionsEnabled: Boolean = true,
|
||||
val doubleTapActionEnabled: Boolean = false,
|
||||
val postLayout: PostLayout = PostLayout.Card,
|
||||
val fullHeightImages: Boolean = true,
|
||||
val separateUpAndDownVotes: Boolean = false,
|
||||
|
@ -198,13 +198,13 @@ class PostListScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
onSelectSortType = rememberCallback {
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
},
|
||||
@ -315,6 +315,14 @@ class PostListScreen : Screen {
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
directions = if (!uiState.isLogged) {
|
||||
emptySet()
|
||||
} else {
|
||||
setOf(
|
||||
DismissDirection.StartToEnd,
|
||||
DismissDirection.EndToStart,
|
||||
)
|
||||
},
|
||||
backgroundColor = rememberCallbackArgs {
|
||||
when (it) {
|
||||
DismissValue.DismissedToStart -> upvoteColor
|
||||
@ -356,51 +364,72 @@ class PostListScreen : Screen {
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled || !uiState.isLogged) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
if (uiState.isLogged) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.DownVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
if (uiState.isLogged) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.DownVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.SavePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
if (uiState.isLogged) {
|
||||
model.reduce(
|
||||
PostListMviModel.Intent.SavePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onReply = rememberCallback(model) {
|
||||
val screen = CreateCommentScreen(originalPost = post)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
if (uiState.isLogged) {
|
||||
val screen =
|
||||
CreateCommentScreen(originalPost = post)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
}
|
||||
},
|
||||
onImageClick = rememberCallbackArgs(model, post) { url ->
|
||||
model.reduce(PostListMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url)
|
||||
)
|
||||
},
|
||||
@ -411,7 +440,7 @@ class PostListScreen : Screen {
|
||||
stringResource(MR.strings.post_action_share)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
if (uiState.isLogged) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.Hide,
|
||||
@ -425,7 +454,7 @@ class PostListScreen : Screen {
|
||||
stringResource(MR.strings.post_action_see_raw)
|
||||
)
|
||||
)
|
||||
if (uiState.currentUserId != null) {
|
||||
if (uiState.isLogged) {
|
||||
add(
|
||||
Option(
|
||||
OptionId.CrossPost,
|
||||
@ -461,24 +490,21 @@ class PostListScreen : Screen {
|
||||
)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(editedPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(postId = post.id)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.CrossPost -> {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(crossPost = post)
|
||||
)
|
||||
}
|
||||
|
||||
OptionId.SeeRaw -> {
|
||||
|
@ -106,6 +106,7 @@ class PostListViewModel(
|
||||
it.copy(
|
||||
blurNsfw = settings.blurNsfw,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
fullHeightImages = settings.fullHeightImages,
|
||||
|
@ -47,7 +47,7 @@ internal fun PostsTopBar(
|
||||
onHamburgerTapped != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onHamburgerTapped()
|
||||
},
|
||||
),
|
||||
@ -60,7 +60,7 @@ internal fun PostsTopBar(
|
||||
listingType != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
@ -80,7 +80,7 @@ internal fun PostsTopBar(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = Spacing.s)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
@ -115,7 +115,7 @@ internal fun PostsTopBar(
|
||||
if (sortType != null) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectSortType?.invoke()
|
||||
},
|
||||
),
|
||||
|
@ -105,7 +105,7 @@ object InboxScreen : Tab {
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
scope.launch {
|
||||
drawerCoordinator.toggleDrawer()
|
||||
}
|
||||
@ -128,9 +128,9 @@ object InboxScreen : Tab {
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = InboxTypeSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
text = text,
|
||||
@ -142,7 +142,7 @@ object InboxScreen : Tab {
|
||||
if (uiState.isLogged == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(InboxMviModel.Intent.ReadAll)
|
||||
},
|
||||
),
|
||||
|
@ -46,6 +46,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.Co
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardType
|
||||
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.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailScreen
|
||||
@ -181,7 +183,7 @@ class InboxMentionsScreen : Tab {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
onOpenPost = rememberCallbackArgs { post ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
highlightCommentId = mention.comment.id,
|
||||
@ -189,12 +191,12 @@ class InboxMentionsScreen : Tab {
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
@ -208,6 +210,39 @@ class InboxMentionsScreen : Tab {
|
||||
)
|
||||
)
|
||||
},
|
||||
options = buildList {
|
||||
add(
|
||||
Option(
|
||||
OptionId.MarkRead,
|
||||
stringResource(MR.strings.inbox_action_mark_read)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.MarkUnread,
|
||||
stringResource(MR.strings.inbox_action_mark_unread)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.MarkRead -> model.reduce(
|
||||
InboxMentionsMviModel.Intent.MarkAsRead(
|
||||
read = true,
|
||||
id = mention.id,
|
||||
),
|
||||
)
|
||||
|
||||
OptionId.MarkUnread -> model.reduce(
|
||||
InboxMentionsMviModel.Intent.MarkAsRead(
|
||||
read = false,
|
||||
id = mention.id,
|
||||
),
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -1,32 +1,47 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.inbox.messages
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.MoreHoriz
|
||||
import androidx.compose.material.icons.filled.Schedule
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.FilterQuality
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.layout.positionInParent
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.DpOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.IconSize
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomDropDown
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomImage
|
||||
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.PlaceholderImage
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.ScaledContent
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.prettifyDate
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.UserModel
|
||||
|
||||
@Composable
|
||||
@ -36,24 +51,30 @@ internal fun ChatCard(
|
||||
lastMessage: String,
|
||||
lastMessageDate: String? = null,
|
||||
modifier: Modifier = Modifier,
|
||||
options: List<Option> = emptyList(),
|
||||
onOpenUser: ((UserModel) -> Unit)? = null,
|
||||
onOpen: (() -> Unit)? = null,
|
||||
onOptionSelected: ((OptionId) -> Unit)? = null,
|
||||
) {
|
||||
var optionsExpanded by remember { mutableStateOf(false) }
|
||||
var optionsOffset by remember { mutableStateOf(Offset.Zero) }
|
||||
val creatorName = user?.name.orEmpty()
|
||||
val creatorHost = user?.host.orEmpty()
|
||||
val creatorAvatar = user?.avatar.orEmpty()
|
||||
val iconSize = IconSize.xl
|
||||
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(Spacing.xs)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onOpen?.invoke()
|
||||
},
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.m),
|
||||
) {
|
||||
val creatorName = user?.name.orEmpty()
|
||||
val creatorHost = user?.host.orEmpty()
|
||||
val creatorAvatar = user?.avatar.orEmpty()
|
||||
val iconSize = 46.dp
|
||||
|
||||
|
||||
if (creatorAvatar.isNotEmpty()) {
|
||||
CustomImage(
|
||||
@ -62,7 +83,7 @@ internal fun ChatCard(
|
||||
.size(iconSize)
|
||||
.clip(RoundedCornerShape(iconSize / 2))
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (user != null) {
|
||||
onOpenUser?.invoke(user)
|
||||
}
|
||||
@ -77,7 +98,7 @@ internal fun ChatCard(
|
||||
} else {
|
||||
PlaceholderImage(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (user != null) {
|
||||
onOpenUser?.invoke(user)
|
||||
}
|
||||
@ -115,22 +136,67 @@ internal fun ChatCard(
|
||||
|
||||
// last message date
|
||||
if (lastMessageDate != null) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val buttonModifier = Modifier.size(IconSize.m).padding(3.25.dp)
|
||||
Icon(
|
||||
modifier = buttonModifier.padding(1.dp),
|
||||
imageVector = Icons.Default.Schedule,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Text(
|
||||
text = lastMessageDate.prettifyDate(),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
Box {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(Spacing.xxs),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
val buttonModifier = Modifier.size(IconSize.m).padding(3.5.dp)
|
||||
Icon(
|
||||
modifier = buttonModifier.padding(1.dp),
|
||||
imageVector = Icons.Default.Schedule,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
Text(
|
||||
text = lastMessageDate.prettifyDate(),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface,
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
if (options.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = buttonModifier
|
||||
.padding(top = Spacing.xxs)
|
||||
.onGloballyPositioned {
|
||||
optionsOffset = it.positionInParent()
|
||||
}
|
||||
.onClick(
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = true
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.MoreHoriz,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
CustomDropDown(
|
||||
expanded = optionsExpanded,
|
||||
onDismiss = {
|
||||
optionsExpanded = false
|
||||
},
|
||||
offset = DpOffset(
|
||||
x = optionsOffset.x.toLocalDp(),
|
||||
y = optionsOffset.y.toLocalDp(),
|
||||
),
|
||||
) {
|
||||
options.forEach { option ->
|
||||
Text(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = Spacing.m,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
onClick = rememberCallback {
|
||||
optionsExpanded = false
|
||||
onOptionSelected?.invoke(option.id)
|
||||
},
|
||||
),
|
||||
text = option.text,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,18 +118,18 @@ class InboxMessagesScreen : Tab {
|
||||
lastMessage = chat.content.orEmpty(),
|
||||
lastMessageDate = chat.publishDate,
|
||||
onOpenUser = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user)
|
||||
)
|
||||
},
|
||||
onOpen = rememberCallback {
|
||||
val userId = otherUser?.id
|
||||
if (userId != null) {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
InboxChatScreen(userId)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
item {
|
||||
|
@ -46,6 +46,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.Co
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.InboxCardType
|
||||
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.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getNavigationCoordinator
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.postdetail.PostDetailScreen
|
||||
@ -180,7 +182,7 @@ class InboxRepliesScreen : Tab {
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
onOpenPost = rememberCallbackArgs { post ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = post,
|
||||
highlightCommentId = reply.comment.id,
|
||||
@ -188,12 +190,12 @@ class InboxRepliesScreen : Tab {
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
@ -203,6 +205,39 @@ class InboxRepliesScreen : Tab {
|
||||
onDownVote = rememberCallbackArgs(model) {
|
||||
model.reduce(InboxRepliesMviModel.Intent.DownVoteComment(reply.id))
|
||||
},
|
||||
options = buildList {
|
||||
add(
|
||||
Option(
|
||||
OptionId.MarkRead,
|
||||
stringResource(MR.strings.inbox_action_mark_read)
|
||||
)
|
||||
)
|
||||
add(
|
||||
Option(
|
||||
OptionId.MarkUnread,
|
||||
stringResource(MR.strings.inbox_action_mark_unread)
|
||||
)
|
||||
)
|
||||
},
|
||||
onOptionSelected = rememberCallbackArgs(model) { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.MarkRead -> model.reduce(
|
||||
InboxRepliesMviModel.Intent.MarkAsRead(
|
||||
read = true,
|
||||
id = reply.id,
|
||||
),
|
||||
)
|
||||
|
||||
OptionId.MarkUnread -> model.reduce(
|
||||
InboxRepliesMviModel.Intent.MarkAsRead(
|
||||
read = false,
|
||||
id = reply.id,
|
||||
),
|
||||
)
|
||||
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -142,8 +142,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
user = user,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
onOpenImage = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()
|
||||
?.push(ZoomableImageScreen(url))
|
||||
navigationCoordinator.pushScreen(ZoomableImageScreen(url))
|
||||
},
|
||||
)
|
||||
SectionSelector(
|
||||
@ -193,17 +192,17 @@ internal object ProfileLoggedScreen : Tab {
|
||||
hideAuthor = true,
|
||||
blurNsfw = false,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -264,7 +263,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
)
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreatePostScreen(
|
||||
editedPost = post,
|
||||
)
|
||||
@ -324,7 +323,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
hideAuthor = true,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = comment.postId),
|
||||
highlightCommentId = comment.id,
|
||||
@ -386,7 +385,7 @@ internal object ProfileLoggedScreen : Tab {
|
||||
}
|
||||
|
||||
OptionId.Edit -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateCommentScreen(editedComment = comment)
|
||||
)
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class LoginBottomSheet : Screen {
|
||||
}
|
||||
|
||||
LoginBottomSheetMviModel.Effect.LoginSuccess -> {
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -125,12 +125,11 @@ class LoginBottomSheet : Screen {
|
||||
IconButton(
|
||||
modifier = Modifier.align(Alignment.TopEnd),
|
||||
onClick = {
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
handleUrl(
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
navigationCoordinator.handleUrl(
|
||||
url = HELP_URL,
|
||||
openExternal = settingsRepository.currentSettings.value.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
) {
|
||||
@ -181,7 +180,7 @@ class LoginBottomSheet : Screen {
|
||||
if (uiState.instanceName.isNotEmpty()) {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback(model) {
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(
|
||||
LoginBottomSheetMviModel.Intent.SetInstanceName("")
|
||||
)
|
||||
@ -254,7 +253,7 @@ class LoginBottomSheet : Screen {
|
||||
trailingIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
transformation =
|
||||
if (transformation == VisualTransformation.None) {
|
||||
PasswordVisualTransformation()
|
||||
|
@ -86,7 +86,7 @@ internal object ProfileMainScreen : Tab {
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
scope.launch {
|
||||
drawerCoordinator.toggleDrawer()
|
||||
}
|
||||
@ -108,9 +108,8 @@ internal object ProfileMainScreen : Tab {
|
||||
if (uiState.logged == true) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getBottomNavigator()
|
||||
?.show(ManageAccountsScreen())
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.showBottomSheet(ManageAccountsScreen())
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ManageAccounts,
|
||||
@ -122,7 +121,7 @@ internal object ProfileMainScreen : Tab {
|
||||
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(ProfileMainMviModel.Intent.Logout)
|
||||
},
|
||||
),
|
||||
|
@ -64,7 +64,7 @@ class ManageAccountsScreen : Screen {
|
||||
model.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
ManageAccountsMviModel.Effect.Close -> {
|
||||
navigationCoordinator.getBottomNavigator()?.hide()
|
||||
navigationCoordinator.hideBottomSheet()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -104,7 +104,7 @@ class ManageAccountsScreen : Screen {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(ManageAccountsMviModel.Intent.SwitchAccount(idx))
|
||||
},
|
||||
)
|
||||
@ -151,7 +151,7 @@ class ManageAccountsScreen : Screen {
|
||||
Spacer(modifier = Modifier.height(Spacing.m))
|
||||
Button(
|
||||
onClick = {
|
||||
navigationCoordinator.getBottomNavigator()?.show(LoginBottomSheet())
|
||||
navigationCoordinator.showBottomSheet(LoginBottomSheet())
|
||||
},
|
||||
) {
|
||||
Row(
|
||||
|
@ -42,7 +42,7 @@ internal object ProfileNotLoggedScreen : Tab {
|
||||
Button(
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
onClick = {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
LoginBottomSheet(),
|
||||
)
|
||||
},
|
||||
|
@ -18,6 +18,7 @@ interface ExploreMviModel :
|
||||
data class SetListingType(val value: ListingType) : Intent
|
||||
data class SetSortType(val value: SortType) : Intent
|
||||
data class SetResultType(val value: SearchResultType) : Intent
|
||||
data object HapticIndication : Intent
|
||||
data class UpVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class DownVotePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
data class SavePost(val id: Int, val feedback: Boolean = false) : Intent
|
||||
@ -31,6 +32,8 @@ interface ExploreMviModel :
|
||||
val loading: Boolean = false,
|
||||
val canFetchMore: Boolean = true,
|
||||
val isLogged: Boolean = false,
|
||||
val swipeActionsEnabled: Boolean = false,
|
||||
val doubleTapActionEnabled: Boolean = false,
|
||||
val blurNsfw: Boolean = true,
|
||||
val instance: String = "",
|
||||
val searchText: String = "",
|
||||
|
@ -15,12 +15,16 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowCircleDown
|
||||
import androidx.compose.material.icons.filled.ArrowCircleUp
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material.pullrefresh.PullRefreshIndicator
|
||||
import androidx.compose.material.pullrefresh.pullRefresh
|
||||
import androidx.compose.material.pullrefresh.rememberPullRefreshState
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DismissDirection
|
||||
import androidx.compose.material3.DismissValue
|
||||
import androidx.compose.material3.Divider
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@ -42,6 +46,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
@ -52,6 +57,7 @@ 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.data.PostLayout
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.communitydetail.CommunityDetailScreen
|
||||
@ -59,6 +65,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.Comment
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CommunityItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.PostCardPlaceholder
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.SwipeableCard
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.UserItem
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.createcomment.CreateCommentScreen
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.di.getDrawerCoordinator
|
||||
@ -114,6 +121,12 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
val settingsRepository = remember { getSettingsRepository() }
|
||||
val settings by settingsRepository.currentSettings.collectAsState()
|
||||
val themeRepository = remember { getThemeRepository() }
|
||||
val upvoteColor by themeRepository.upvoteColor.collectAsState()
|
||||
val downvoteColor by themeRepository.downvoteColor.collectAsState()
|
||||
val defaultUpvoteColor = MaterialTheme.colorScheme.primary
|
||||
val defaultDownVoteColor = MaterialTheme.colorScheme.tertiary
|
||||
|
||||
DisposableEffect(key) {
|
||||
onDispose {
|
||||
notificationCenter.removeObserver(key)
|
||||
@ -176,14 +189,14 @@ class ExploreScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
onSelectSortType = rememberCallback {
|
||||
focusManager.clearFocus()
|
||||
val sheet = SortBottomSheet(
|
||||
expandTop = true,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
onHamburgerTapped = rememberCallback {
|
||||
scope.launch {
|
||||
@ -217,7 +230,7 @@ class ExploreScreen : Screen {
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(ExploreMviModel.Intent.SetSearch(""))
|
||||
}
|
||||
@ -308,8 +321,8 @@ class ExploreScreen : Screen {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(result),
|
||||
)
|
||||
},
|
||||
@ -320,61 +333,110 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
|
||||
is PostModel -> {
|
||||
PostCard(
|
||||
post = result,
|
||||
postLayout = uiState.postLayout,
|
||||
fullHeightImage = uiState.fullHeightImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(result),
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
backgroundColor = rememberCallbackArgs {
|
||||
when (it) {
|
||||
DismissValue.DismissedToStart -> upvoteColor
|
||||
?: defaultUpvoteColor
|
||||
|
||||
DismissValue.DismissedToEnd -> downvoteColor
|
||||
?: defaultDownVoteColor
|
||||
|
||||
DismissValue.Default -> Color.Transparent
|
||||
}
|
||||
},
|
||||
onGestureBegin = {
|
||||
model.reduce(ExploreMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(ExploreMviModel.Intent.UpVotePost(result.id))
|
||||
},
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(ExploreMviModel.Intent.DownVotePost(result.id))
|
||||
},
|
||||
swipeContent = { direction ->
|
||||
val icon = when (direction) {
|
||||
DismissDirection.StartToEnd -> Icons.Default.ArrowCircleDown
|
||||
DismissDirection.EndToStart -> Icons.Default.ArrowCircleUp
|
||||
}
|
||||
androidx.compose.material.Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVotePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVotePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SavePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = rememberCallback {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = result,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
ZoomableImageScreen(url),
|
||||
content = {
|
||||
PostCard(
|
||||
post = result,
|
||||
postLayout = uiState.postLayout,
|
||||
fullHeightImage = uiState.fullHeightImages,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(result),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVotePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs { community ->
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs { user ->
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVotePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVotePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SavePost(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = rememberCallback {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = result,
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
onImageClick = rememberCallbackArgs { url ->
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -386,59 +448,124 @@ class ExploreScreen : Screen {
|
||||
}
|
||||
|
||||
is CommentModel -> {
|
||||
CommentCard(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
comment = result,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = result.postId),
|
||||
highlightCommentId = result.id,
|
||||
),
|
||||
SwipeableCard(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = uiState.swipeActionsEnabled,
|
||||
directions = if (!uiState.isLogged) {
|
||||
emptySet()
|
||||
} else {
|
||||
setOf(
|
||||
DismissDirection.StartToEnd,
|
||||
DismissDirection.EndToStart,
|
||||
)
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
backgroundColor = rememberCallbackArgs {
|
||||
when (it) {
|
||||
DismissValue.DismissedToStart -> upvoteColor
|
||||
?: defaultUpvoteColor
|
||||
|
||||
DismissValue.DismissedToEnd -> downvoteColor
|
||||
?: defaultDownVoteColor
|
||||
|
||||
DismissValue.Default -> Color.Transparent
|
||||
}
|
||||
},
|
||||
onGestureBegin = rememberCallback(model) {
|
||||
model.reduce(ExploreMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVoteComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
id = result.id
|
||||
),
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
onDismissToEnd = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVoteComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
id = result.id
|
||||
),
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SaveComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
swipeContent = { direction ->
|
||||
val icon = when (direction) {
|
||||
DismissDirection.StartToEnd -> Icons.Default.ArrowCircleDown
|
||||
DismissDirection.EndToStart -> Icons.Default.ArrowCircleUp
|
||||
}
|
||||
androidx.compose.material.Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
)
|
||||
},
|
||||
onReply = rememberCallback {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = PostModel(id = result.postId),
|
||||
originalComment = result,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
CommunityDetailScreen(it)
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
UserDetailScreen(it)
|
||||
content = {
|
||||
CommentCard(
|
||||
modifier = Modifier.background(MaterialTheme.colorScheme.background),
|
||||
comment = result,
|
||||
separateUpAndDownVotes = uiState.separateUpAndDownVotes,
|
||||
autoLoadImages = uiState.autoLoadImages,
|
||||
hideIndent = true,
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(
|
||||
post = PostModel(id = result.postId),
|
||||
highlightCommentId = result.id,
|
||||
),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (!uiState.doubleTapActionEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVoteComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onUpVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.UpVoteComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onDownVote = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.DownVoteComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onSave = rememberCallback(model) {
|
||||
model.reduce(
|
||||
ExploreMviModel.Intent.SaveComment(
|
||||
id = result.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
},
|
||||
onReply = rememberCallback {
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = PostModel(id = result.postId),
|
||||
originalComment = result,
|
||||
)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
onOpenCommunity = rememberCallbackArgs {
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(it)
|
||||
)
|
||||
},
|
||||
onOpenCreator = rememberCallbackArgs {
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(it)
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -453,8 +580,8 @@ class ExploreScreen : Screen {
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(result),
|
||||
)
|
||||
},
|
||||
|
@ -46,7 +46,7 @@ internal fun ExploreTopBar(
|
||||
onHamburgerTapped != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onHamburgerTapped()
|
||||
},
|
||||
),
|
||||
@ -59,7 +59,7 @@ internal fun ExploreTopBar(
|
||||
listingType != null -> {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
@ -79,7 +79,7 @@ internal fun ExploreTopBar(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = Spacing.s)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectListingType?.invoke()
|
||||
},
|
||||
),
|
||||
@ -109,7 +109,7 @@ internal fun ExploreTopBar(
|
||||
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onSelectSortType?.invoke()
|
||||
},
|
||||
),
|
||||
|
@ -89,6 +89,8 @@ class ExploreViewModel(
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
fullHeightImages = settings.fullHeightImages,
|
||||
swipeActionsEnabled = settings.enableSwipeActions,
|
||||
doubleTapActionEnabled = settings.enableDoubleTapAction,
|
||||
)
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -126,6 +128,7 @@ class ExploreViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
ExploreMviModel.Intent.HapticIndication -> hapticFeedback.vibrate()
|
||||
is ExploreMviModel.Intent.SetSearch -> setSearch(intent.value)
|
||||
is ExploreMviModel.Intent.SetListingType -> changeListingType(intent.value)
|
||||
is ExploreMviModel.Intent.SetSortType -> changeSortType(intent.value)
|
||||
|
@ -108,8 +108,8 @@ class ManageSubscriptionsScreen : Screen {
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigatorCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -178,8 +178,8 @@ class ManageSubscriptionsScreen : Screen {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigatorCoordinator.pushScreen(
|
||||
MultiCommunityEditorScreen()
|
||||
)
|
||||
},
|
||||
@ -206,7 +206,7 @@ class ManageSubscriptionsScreen : Screen {
|
||||
model.reduce(ManageSubscriptionsMviModel.Intent.HapticIndication)
|
||||
},
|
||||
onDismissToStart = rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
navigatorCoordinator.pushScreen(
|
||||
MultiCommunityEditorScreen(community),
|
||||
)
|
||||
},
|
||||
@ -233,8 +233,8 @@ class ManageSubscriptionsScreen : Screen {
|
||||
MultiCommunityItem(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.background).onClick(
|
||||
rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigatorCoordinator.pushScreen(
|
||||
MultiCommunityScreen(community),
|
||||
)
|
||||
},
|
||||
@ -294,8 +294,8 @@ class ManageSubscriptionsScreen : Screen {
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.background)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
navigatorCoordinator.getRootNavigator()?.push(
|
||||
onClick = rememberCallback {
|
||||
navigatorCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
|
@ -159,8 +159,8 @@ class MultiCommunityScreen(
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -184,9 +184,9 @@ class MultiCommunityScreen(
|
||||
if (sortType != null) {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
val sheet = SortBottomSheet(expandTop = true)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
),
|
||||
imageVector = sortType.toIcon(),
|
||||
@ -316,17 +316,29 @@ class MultiCommunityScreen(
|
||||
blurNsfw = uiState.blurNsfw,
|
||||
onClick = {
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
PostDetailScreen(post),
|
||||
)
|
||||
},
|
||||
onDoubleClick = if (uiState.swipeActionsEnabled) {
|
||||
null
|
||||
} else {
|
||||
rememberCallback(model) {
|
||||
model.reduce(
|
||||
MultiCommunityMviModel.Intent.UpVotePost(
|
||||
id = post.id,
|
||||
feedback = true,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
onOpenCommunity = { community ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(community),
|
||||
)
|
||||
},
|
||||
onOpenCreator = { user ->
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
UserDetailScreen(user),
|
||||
)
|
||||
},
|
||||
@ -358,11 +370,11 @@ class MultiCommunityScreen(
|
||||
val screen = CreateCommentScreen(
|
||||
originalPost = post,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(screen)
|
||||
navigationCoordinator.showBottomSheet(screen)
|
||||
},
|
||||
onImageClick = { url ->
|
||||
model.reduce(MultiCommunityMviModel.Intent.MarkAsRead(post.id))
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
ZoomableImageScreen(url),
|
||||
)
|
||||
},
|
||||
@ -391,7 +403,7 @@ class MultiCommunityScreen(
|
||||
onOptionSelected = { optionId ->
|
||||
when (optionId) {
|
||||
OptionId.Report -> {
|
||||
navigationCoordinator.getBottomNavigator()?.show(
|
||||
navigationCoordinator.showBottomSheet(
|
||||
CreateReportScreen(
|
||||
postId = post.id
|
||||
)
|
||||
|
@ -88,7 +88,7 @@ class MultiCommunityEditorScreen(
|
||||
model.effects.onEach {
|
||||
when (it) {
|
||||
MultiCommunityEditorMviModel.Effect.Close -> {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
navigationCoordinator.popScreen()
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
@ -114,8 +114,8 @@ class MultiCommunityEditorScreen(
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
navigationCoordinator.getRootNavigator()?.pop()
|
||||
onClick = rememberCallback {
|
||||
navigationCoordinator.popScreen()
|
||||
},
|
||||
),
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
@ -219,7 +219,7 @@ class MultiCommunityEditorScreen(
|
||||
it
|
||||
}
|
||||
}.onClick(
|
||||
rememberCallback(model) {
|
||||
onClick = rememberCallback(model) {
|
||||
model.reduce(
|
||||
MultiCommunityEditorMviModel.Intent.SelectImage(
|
||||
idx,
|
||||
@ -260,7 +260,7 @@ class MultiCommunityEditorScreen(
|
||||
it
|
||||
}
|
||||
}.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
model.reduce(
|
||||
MultiCommunityEditorMviModel.Intent.SelectImage(
|
||||
null,
|
||||
@ -307,7 +307,7 @@ class MultiCommunityEditorScreen(
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
if (uiState.searchText.isNotEmpty()) {
|
||||
model.reduce(
|
||||
MultiCommunityEditorMviModel.Intent.SetSearch("")
|
||||
|
@ -75,7 +75,7 @@ class AboutDialog : Screen {
|
||||
viewModel.effects.onEach { effect ->
|
||||
when (effect) {
|
||||
is AboutDialogMviModel.Effect.OpenCommunity -> {
|
||||
navigationCoordinator.getRootNavigator()?.push(
|
||||
navigationCoordinator.pushScreen(
|
||||
CommunityDetailScreen(
|
||||
community = effect.community,
|
||||
otherInstance = effect.instance,
|
||||
@ -122,11 +122,10 @@ class AboutDialog : Screen {
|
||||
vector = Icons.Default.OpenInBrowser,
|
||||
textDecoration = TextDecoration.Underline,
|
||||
onClick = {
|
||||
handleUrl(
|
||||
navigationCoordinator.handleUrl(
|
||||
url = CHANGELOG_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
}
|
||||
)
|
||||
@ -134,11 +133,10 @@ class AboutDialog : Screen {
|
||||
item {
|
||||
Button(
|
||||
onClick = {
|
||||
handleUrl(
|
||||
navigationCoordinator.handleUrl(
|
||||
url = REPORT_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
) {
|
||||
@ -166,11 +164,10 @@ class AboutDialog : Screen {
|
||||
text = stringResource(MR.strings.settings_about_view_github),
|
||||
textDecoration = TextDecoration.Underline,
|
||||
onClick = {
|
||||
handleUrl(
|
||||
navigationCoordinator.handleUrl(
|
||||
url = WEBSITE_URL,
|
||||
openExternal = settings.openUrlsInExternalBrowser,
|
||||
uriHandler = uriHandler,
|
||||
navigator = navigationCoordinator.getRootNavigator(),
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -212,7 +209,7 @@ class AboutDialog : Screen {
|
||||
horizontal = Spacing.xs,
|
||||
vertical = Spacing.s,
|
||||
).onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onClick?.invoke()
|
||||
},
|
||||
),
|
||||
|
@ -32,6 +32,7 @@ interface SettingsMviModel :
|
||||
data class ChangeBlurNsfw(val value: Boolean) : Intent
|
||||
data class ChangeOpenUrlsInExternalBrowser(val value: Boolean) : Intent
|
||||
data class ChangeEnableSwipeActions(val value: Boolean) : Intent
|
||||
data class ChangeEnableDoubleTapAction(val value: Boolean) : Intent
|
||||
data class ChangeCustomSeedColor(val value: Color?) : Intent
|
||||
data class ChangeUpvoteColor(val value: Color?) : Intent
|
||||
data class ChangeDownvoteColor(val value: Color?) : Intent
|
||||
@ -66,6 +67,7 @@ interface SettingsMviModel :
|
||||
val blurNsfw: Boolean = true,
|
||||
val openUrlsInExternalBrowser: Boolean = false,
|
||||
val enableSwipeActions: Boolean = true,
|
||||
val enableDoubleTapAction: Boolean = true,
|
||||
val crashReportEnabled: Boolean = false,
|
||||
val separateUpAndDownVotes: Boolean = false,
|
||||
val autoLoadImages: Boolean = false,
|
||||
|
@ -65,10 +65,10 @@ import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.SortBottomS
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.modals.ThemeBottomSheet
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterContractKeys
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.di.getNotificationCenter
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.getPrettyDuration
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.datetime.getPrettyDuration
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLanguageName
|
||||
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp
|
||||
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.ListingType
|
||||
@ -278,7 +278,7 @@ class SettingsScreen : Screen {
|
||||
navigationIcon = {
|
||||
Image(
|
||||
modifier = Modifier.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
scope.launch {
|
||||
drawerCoordinator.toggleDrawer()
|
||||
}
|
||||
@ -318,7 +318,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.lang.toLanguageName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = LanguageBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -328,13 +328,14 @@ class SettingsScreen : Screen {
|
||||
value = uiState.uiTheme.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = ThemeBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
// dynamic colors
|
||||
if (uiState.supportsDynamicColors) {
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_dynamic_colors),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_dynamic_colors),
|
||||
value = uiState.dynamicColors,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -342,7 +343,8 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
val colorSchemeProvider = remember { getColorSchemeProvider() }
|
||||
@ -355,7 +357,7 @@ class SettingsScreen : Screen {
|
||||
).primary,
|
||||
onTap = rememberCallback {
|
||||
val sheet = ColorBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
// upvote and downvote colors
|
||||
@ -380,7 +382,7 @@ class SettingsScreen : Screen {
|
||||
value = uiState.uiFontFamily.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = FontFamilyBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
// font scale
|
||||
@ -396,7 +398,7 @@ class SettingsScreen : Screen {
|
||||
),
|
||||
contract = NotificationCenterContractKeys.ChangeUiFontSize
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
SettingsRow(
|
||||
@ -406,7 +408,7 @@ class SettingsScreen : Screen {
|
||||
val sheet = FontScaleBottomSheet(
|
||||
contract = NotificationCenterContractKeys.ChangeContentFontSize,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -416,12 +418,13 @@ class SettingsScreen : Screen {
|
||||
value = uiState.postLayout.toReadableName(),
|
||||
onTap = rememberCallback {
|
||||
val sheet = PostLayoutBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
// separate upvotes and downvotes
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_separate_up_and_downvotes),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_separate_up_and_downvotes),
|
||||
value = uiState.separateUpAndDownVotes,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -429,10 +432,12 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// full height images
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_full_height_images),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_full_height_images),
|
||||
value = uiState.fullHeightImages,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -440,10 +445,12 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// navigation bar titles
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_navigation_bar_titles_visible),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_navigation_bar_titles_visible),
|
||||
value = uiState.navBarTitlesVisible,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -451,7 +458,8 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
SettingsHeader(
|
||||
icon = Icons.Default.Tune,
|
||||
@ -466,7 +474,7 @@ class SettingsScreen : Screen {
|
||||
val sheet = ListingTypeBottomSheet(
|
||||
isLogged = uiState.isLogged,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -479,7 +487,7 @@ class SettingsScreen : Screen {
|
||||
expandTop = true,
|
||||
contract = NotificationCenterContractKeys.ChangeSortType,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -498,7 +506,7 @@ class SettingsScreen : Screen {
|
||||
SortType.Controversial,
|
||||
),
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -517,7 +525,7 @@ class SettingsScreen : Screen {
|
||||
),
|
||||
onTap = rememberCallback {
|
||||
val sheet = DurationBottomSheet()
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
@ -535,12 +543,13 @@ class SettingsScreen : Screen {
|
||||
max = screenWidth,
|
||||
initial = uiState.zombieModeScrollAmount,
|
||||
)
|
||||
navigationCoordinator.getBottomNavigator()?.show(sheet)
|
||||
navigationCoordinator.showBottomSheet(sheet)
|
||||
},
|
||||
)
|
||||
|
||||
// swipe actions
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_enable_swipe_actions),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_enable_swipe_actions),
|
||||
value = uiState.enableSwipeActions,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -548,10 +557,25 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// double tap
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_enable_double_tap),
|
||||
value = uiState.enableDoubleTapAction,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
SettingsMviModel.Intent.ChangeEnableDoubleTapAction(
|
||||
value
|
||||
)
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
// bottom navigation hiding
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_hide_navigation_bar),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_hide_navigation_bar),
|
||||
value = uiState.hideNavigationBarWhileScrolling,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -559,10 +583,12 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// URL open
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_open_url_external),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_open_url_external),
|
||||
value = uiState.openUrlsInExternalBrowser,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -570,10 +596,12 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// auto-expand comments
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_auto_expand_comments),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_auto_expand_comments),
|
||||
value = uiState.autoExpandComments,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -581,10 +609,12 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// image loading
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_auto_load_images),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_auto_load_images),
|
||||
value = uiState.autoLoadImages,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(
|
||||
@ -592,7 +622,8 @@ class SettingsScreen : Screen {
|
||||
value
|
||||
)
|
||||
)
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
SettingsHeader(
|
||||
icon = Icons.Default.Shield,
|
||||
@ -600,16 +631,19 @@ class SettingsScreen : Screen {
|
||||
)
|
||||
|
||||
// NSFW options
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_include_nsfw),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_include_nsfw),
|
||||
value = uiState.includeNsfw,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeIncludeNsfw(value))
|
||||
})
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_blur_nsfw),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_blur_nsfw),
|
||||
value = uiState.blurNsfw,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeBlurNsfw(value))
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
SettingsHeader(
|
||||
icon = Icons.Default.BugReport,
|
||||
@ -617,11 +651,13 @@ class SettingsScreen : Screen {
|
||||
)
|
||||
|
||||
// enable crash report
|
||||
SettingsSwitchRow(title = stringResource(MR.strings.settings_enable_crash_report),
|
||||
SettingsSwitchRow(
|
||||
title = stringResource(MR.strings.settings_enable_crash_report),
|
||||
value = uiState.crashReportEnabled,
|
||||
onValueChanged = rememberCallbackArgs(model) { value ->
|
||||
model.reduce(SettingsMviModel.Intent.ChangeCrashReportEnabled(value))
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
// about
|
||||
SettingsRow(
|
||||
|
@ -109,6 +109,7 @@ class SettingsViewModel(
|
||||
supportsDynamicColors = colorSchemeProvider.supportsDynamicColors,
|
||||
openUrlsInExternalBrowser = settings.openUrlsInExternalBrowser,
|
||||
enableSwipeActions = settings.enableSwipeActions,
|
||||
enableDoubleTapAction = settings.enableDoubleTapAction,
|
||||
crashReportEnabled = crashReportConfiguration.isEnabled(),
|
||||
separateUpAndDownVotes = settings.separateUpAndDownVotes,
|
||||
autoLoadImages = settings.autoLoadImages,
|
||||
@ -179,6 +180,10 @@ class SettingsViewModel(
|
||||
changeEnableSwipeActions(intent.value)
|
||||
}
|
||||
|
||||
is SettingsMviModel.Intent.ChangeEnableDoubleTapAction -> {
|
||||
changeEnableDoubleTapAction(intent.value)
|
||||
}
|
||||
|
||||
is SettingsMviModel.Intent.ChangeCustomSeedColor -> changeCustomSeedColor(
|
||||
intent.value
|
||||
)
|
||||
@ -389,6 +394,16 @@ class SettingsViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeEnableDoubleTapAction(value: Boolean) {
|
||||
mvi.updateState { it.copy(enableDoubleTapAction = value) }
|
||||
mvi.scope?.launch {
|
||||
val settings = settingsRepository.currentSettings.value.copy(
|
||||
enableDoubleTapAction = value
|
||||
)
|
||||
saveSettings(settings)
|
||||
}
|
||||
}
|
||||
|
||||
private fun changePostLayout(value: PostLayout) {
|
||||
themeRepository.changePostLayout(value)
|
||||
mvi.scope?.launch {
|
||||
|
@ -2,6 +2,7 @@ package com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -24,25 +25,37 @@ internal fun SettingsColorRow(
|
||||
title: String,
|
||||
value: Color,
|
||||
modifier: Modifier = Modifier,
|
||||
subtitle: String? = null,
|
||||
onTap: (() -> Unit)? = null,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(vertical = Spacing.s, horizontal = Spacing.m)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onTap?.invoke()
|
||||
},
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -18,25 +19,37 @@ internal fun SettingsRow(
|
||||
title: String,
|
||||
value: String,
|
||||
modifier: Modifier = Modifier,
|
||||
subtitle: String? = null,
|
||||
onTap: (() -> Unit)? = null,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier
|
||||
.padding(vertical = Spacing.s, horizontal = Spacing.m)
|
||||
.onClick(
|
||||
rememberCallback {
|
||||
onClick = rememberCallback {
|
||||
onTap?.invoke()
|
||||
},
|
||||
),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(
|
||||
text = value,
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -16,19 +17,31 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
|
||||
internal fun SettingsSwitchRow(
|
||||
title: String,
|
||||
value: Boolean,
|
||||
subtitle: String? = null,
|
||||
onValueChanged: (Boolean) -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = Spacing.m),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Switch(
|
||||
checked = value,
|
||||
|
@ -80,6 +80,8 @@
|
||||
<string name="home_sort_type_top_week_short">week</string>
|
||||
<string name="home_sort_type_top_year">Top year</string>
|
||||
<string name="home_sort_type_top_year_short">year</string>
|
||||
<string name="inbox_action_mark_read">Mark as read</string>
|
||||
<string name="inbox_action_mark_unread">Mark as unread</string>
|
||||
<string name="inbox_chat_message">Message</string>
|
||||
<string name="inbox_item_mention">mentioned you in</string>
|
||||
<string name="inbox_item_reply_comment">replied to your comment in</string>
|
||||
@ -200,6 +202,7 @@
|
||||
<string name="settings_downvote_color">Downvote color</string>
|
||||
<string name="settings_dynamic_colors">Use dynamic colors</string>
|
||||
<string name="settings_enable_crash_report">Enable crash reporting</string>
|
||||
<string name="settings_enable_double_tap">Enable double tap action</string>
|
||||
<string name="settings_enable_swipe_actions">Enable swipe actions</string>
|
||||
<string name="settings_full_height_images">Full height images</string>
|
||||
<string name="settings_include_nsfw">Include NSFW contents</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Alle</string>
|
||||
<string name="inbox_listing_type_title">Posteingangstyp</string>
|
||||
<string name="inbox_listing_type_unread">Ungelesen</string>
|
||||
<string name="inbox_action_mark_read">Als gelesen markieren</string>
|
||||
<string name="inbox_action_mark_unread">Als ungelesen markieren</string>
|
||||
<string name="inbox_not_logged_message">Sie sind derzeit nicht angemeldet.\nBitte fügen Sie über
|
||||
den Profilbildschirm ein Konto hinzu, um Ihren Posteingang anzuzeigen.
|
||||
</string>
|
||||
@ -193,6 +195,7 @@
|
||||
<string name="settings_downvote_color">Farbe für Downvotes</string>
|
||||
<string name="settings_dynamic_colors">Verwenden Sie dynamische Farben</string>
|
||||
<string name="settings_enable_crash_report">Absturzberichte aktivieren</string>
|
||||
<string name="settings_enable_double_tap">Doppeltipp-Aktion aktivieren</string>
|
||||
<string name="settings_enable_swipe_actions">Wischaktionen aktivieren</string>
|
||||
<string name="settings_full_height_images">Bilder in voller Höhe</string>
|
||||
<string name="settings_include_nsfw">NSFW-Inhalte einbeziehen</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Όλα</string>
|
||||
<string name="inbox_listing_type_title">Τύπος εισερχομένων</string>
|
||||
<string name="inbox_listing_type_unread">Μη αναγνωσμένα</string>
|
||||
<string name="inbox_action_mark_read">Σημειώσε ως αναγνωσμένο</string>
|
||||
<string name="inbox_action_mark_unread">Σημειώστε ως αδιάβαστο</string>
|
||||
<string name="inbox_not_logged_message">Προς το παρόν, δεν έχετε συνδεθεί.\nΠαρακαλούμε
|
||||
προσθέστε έναν λογαριασμό από την οθόνη προφίλ για να δείτε τα εισερχόμενά σας.
|
||||
</string>
|
||||
@ -194,6 +196,7 @@
|
||||
<string name="settings_downvote_color">Χρώμα ψήφου κατώτερου</string>
|
||||
<string name="settings_dynamic_colors">Χρήση δυναμικών χρωμάτων</string>
|
||||
<string name="settings_enable_crash_report">Ενεργοποίηση αναφοράς καταρρεύσεων</string>
|
||||
<string name="settings_enable_double_tap">Ενεργοποίηση της δράσης διπλού πατήματος</string>
|
||||
<string name="settings_enable_swipe_actions">Ενεργοποίηση κινήσεων σαρώσεων</string>
|
||||
<string name="settings_full_height_images">Εικόνες πλήρους ύψους</string>
|
||||
<string name="settings_include_nsfw">Συμπερίληψη περιεχομένων NSFW</string>
|
||||
|
@ -84,6 +84,8 @@
|
||||
<string name="inbox_item_mention">te ha mencionado en</string>
|
||||
<string name="inbox_item_reply_comment">ha contestado a tu comentario en</string>
|
||||
<string name="inbox_item_reply_post">ha contestado a tu publicación en</string>
|
||||
<string name="inbox_action_mark_read">mMrcar como leído</string>
|
||||
<string name="inbox_action_mark_unread">Marcar como no leído</string>
|
||||
<string name="inbox_listing_type_all">Todos</string>
|
||||
<string name="inbox_listing_type_title">Tipo de mensajes</string>
|
||||
<string name="inbox_listing_type_unread">No leídos</string>
|
||||
@ -192,6 +194,7 @@
|
||||
<string name="settings_downvote_color">Color votos negativos</string>
|
||||
<string name="settings_dynamic_colors">Utilizar colores dinámicos</string>
|
||||
<string name="settings_enable_crash_report">Activar notificación de accidentes</string>
|
||||
<string name="settings_enable_double_tap">Activar la acción de doble toque</string>
|
||||
<string name="settings_enable_swipe_actions">Activar acciones de deslizamiento</string>
|
||||
<string name="settings_full_height_images">Altura completa imágenes</string>
|
||||
<string name="settings_include_nsfw">Incluir contenidos NSFW</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Tous</string>
|
||||
<string name="inbox_listing_type_title">Type de boîte de réception</string>
|
||||
<string name="inbox_listing_type_unread">Non lus</string>
|
||||
<string name="inbox_action_mark_read">Marquer comme lu</string>
|
||||
<string name="inbox_action_mark_unread">Marquer comme non lu</string>
|
||||
<string name="inbox_not_logged_message">Vous n\'êtes pas connecté.\nVeuillez ajouter un compte à
|
||||
partir de l\'écran de profil pour voir votre boîte de réception.
|
||||
</string>
|
||||
@ -192,6 +194,7 @@
|
||||
<string name="settings_downvote_color">Couleur votes négatifs</string>
|
||||
<string name="settings_dynamic_colors">Utiliser couleur dynamique</string>
|
||||
<string name="settings_enable_crash_report">Activer les rapports d\'accidents</string>
|
||||
<string name="settings_enable_double_tap">Activer l\'action double tap</string>
|
||||
<string name="settings_enable_swipe_actions">Activer les actions de glissement</string>
|
||||
<string name="settings_full_height_images">Images en pleine hauteur</string>
|
||||
<string name="settings_include_nsfw">Inclure contenus NSFW</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Tutti</string>
|
||||
<string name="inbox_listing_type_title">Tipo inbox</string>
|
||||
<string name="inbox_listing_type_unread">Non letti</string>
|
||||
<string name="inbox_action_mark_read">Segna come letto</string>
|
||||
<string name="inbox_action_mark_unread">Segna come non letto</string>
|
||||
<string name="inbox_not_logged_message">Login non effettuato.\nAggiungi un account dalla
|
||||
schermata Profilo per accedere alla inbox.
|
||||
</string>
|
||||
@ -192,6 +194,7 @@
|
||||
<string name="settings_downvote_color">Colore voti negativi</string>
|
||||
<string name="settings_dynamic_colors">Usa colori dinamici</string>
|
||||
<string name="settings_enable_crash_report">Abilitare segnalazioni di crash</string>
|
||||
<string name="settings_enable_double_tap">Abilita azione doppio tap</string>
|
||||
<string name="settings_enable_swipe_actions">Consenti azioni allo swipe</string>
|
||||
<string name="settings_full_height_images">Altezza completa immagini</string>
|
||||
<string name="settings_include_nsfw">Includi contenuti NSFW</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Alle</string>
|
||||
<string name="inbox_listing_type_title">Type inbox</string>
|
||||
<string name="inbox_listing_type_unread">Ongelezen</string>
|
||||
<string name="inbox_action_mark_read">Markeren als gelezen</string>
|
||||
<string name="inbox_action_mark_unread">Markeren als ongelezen</string>
|
||||
<string name="inbox_not_logged_message">U bent momenteel niet ingelogd.\nVoeg een account toe
|
||||
vanuit het profielscherm om je inbox te zien.
|
||||
</string>
|
||||
@ -200,6 +202,7 @@
|
||||
<string name="settings_downvote_color">Kleur voor downvote</string>
|
||||
<string name="settings_dynamic_colors">Dynamische kleuren gebruiken</string>
|
||||
<string name="settings_enable_crash_report">Crashrapportage inschakelen</string>
|
||||
<string name="settings_enable_double_tap">Dubbele tik actie inschakelen</string>
|
||||
<string name="settings_enable_swipe_actions">Veegacties inschakelen</string>
|
||||
<string name="settings_full_height_images">Afbeeldingen op volledige hoogte</string>
|
||||
<string name="settings_include_nsfw">NSFW-inhoud opnemen</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Wszystkie</string>
|
||||
<string name="inbox_listing_type_title">Typ skrzynki</string>
|
||||
<string name="inbox_listing_type_unread">Nieprzeczytany</string>
|
||||
<string name="inbox_action_mark_read">Oznacz jako przeczytane</string>
|
||||
<string name="inbox_action_mark_unread">Oznacz jako nieprzeczytane</string>
|
||||
<string name="inbox_not_logged_message">Obecnie nie jesteś zalogowany.\nDodaj konto na ekranie
|
||||
profilu, aby zobaczyć swoją skrzynkę odbiorczą."
|
||||
</string>
|
||||
@ -191,6 +193,7 @@
|
||||
<string name="settings_downvote_color">Kolor głosów negatywnych</string>
|
||||
<string name="settings_dynamic_colors">Używaj dynamicznych kolorów</string>
|
||||
<string name="settings_enable_crash_report">Włącz raportowanie awarii</string>
|
||||
<string name="settings_enable_double_tap">Włącz akcje podwójnego dotknięcia</string>
|
||||
<string name="settings_enable_swipe_actions">Włącz akcje przesuwania</string>
|
||||
<string name="settings_full_height_images">Obrazy o pełnej wysokości</string>
|
||||
<string name="settings_hide_navigation_bar">Ukryj pasek nawigacji podczas przewijania</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Todas</string>
|
||||
<string name="inbox_listing_type_title">Tipo de caixa</string>
|
||||
<string name="inbox_listing_type_unread">Não lidas</string>
|
||||
<string name="inbox_action_mark_read">Marcar como lido</string>
|
||||
<string name="inbox_action_mark_unread">Marcar como não lido</string>
|
||||
<string name="inbox_not_logged_message">Atualmente, não tem sessão iniciada.\nAdicione uma conta
|
||||
a partir do ecrã de perfil para ver a sua caixa de entrada.
|
||||
</string>
|
||||
@ -190,6 +192,7 @@
|
||||
<string name="settings_downvote_color">Cor votos negativos</string>
|
||||
<string name="settings_dynamic_colors">Usar cores dinâmicas</string>
|
||||
<string name="settings_enable_crash_report">Ativar relatórios de falhas</string>
|
||||
<string name="settings_enable_double_tap">Ativar a ação de duplo toque</string>
|
||||
<string name="settings_enable_swipe_actions">Ativar ações de deslizar</string>
|
||||
<string name="settings_full_height_images">Imagens de altura natural</string>
|
||||
<string name="settings_include_nsfw">Incluir conteúdo NSFW</string>
|
||||
|
@ -87,6 +87,8 @@
|
||||
<string name="inbox_listing_type_all">Toate</string>
|
||||
<string name="inbox_listing_type_title">Tip de inbox</string>
|
||||
<string name="inbox_listing_type_unread">Necitit</string>
|
||||
<string name="inbox_action_mark_read">Marchează ca citit</string>
|
||||
<string name="inbox_action_mark_unread">Marchează ca necitit</string>
|
||||
<string name="inbox_not_logged_message">Momentan nu sunteți autentificat.\nVă rugăm să adăugați
|
||||
un cont din ecranul de profil pentru a vedea mesajele.
|
||||
</string>
|
||||
@ -191,6 +193,7 @@
|
||||
<string name="settings_downvote_color">Culoare voturilor negative</string>
|
||||
<string name="settings_dynamic_colors">Folosește culori dinamice</string>
|
||||
<string name="settings_enable_crash_report">Activează raporturi erorilor</string>
|
||||
<string name="settings_enable_double_tap">Activează acțiunea de dublă atingere</string>
|
||||
<string name="settings_enable_swipe_actions">Activează acțiunile de glisare</string>
|
||||
<string name="settings_full_height_images">Imagini pe toată înălțimea</string>
|
||||
<string name="settings_include_nsfw">Include conținuturile NSFW</string>
|
||||
|
@ -172,7 +172,7 @@ fun App() {
|
||||
else -> null
|
||||
}
|
||||
if (newScreen != null) {
|
||||
navigationCoordinator.getRootNavigator()?.push(newScreen)
|
||||
navigationCoordinator.pushScreen(newScreen)
|
||||
}
|
||||
}.launchIn(this)
|
||||
}
|
||||
@ -182,7 +182,6 @@ fun App() {
|
||||
val drawerGestureEnabled by drawerCoordinator.gesturesEnabled.collectAsState()
|
||||
LaunchedEffect(drawerCoordinator) {
|
||||
drawerCoordinator.toggleEvents.onEach { evt ->
|
||||
val navigator = navigationCoordinator.getRootNavigator()
|
||||
when (evt) {
|
||||
DrawerEvent.Toggled -> {
|
||||
drawerState.apply {
|
||||
@ -197,19 +196,19 @@ fun App() {
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenCommunity -> {
|
||||
navigator?.push(CommunityDetailScreen(evt.community))
|
||||
navigationCoordinator.pushScreen(CommunityDetailScreen(evt.community))
|
||||
}
|
||||
|
||||
is DrawerEvent.OpenMultiCommunity -> {
|
||||
navigator?.push(MultiCommunityScreen(evt.community))
|
||||
navigationCoordinator.pushScreen(MultiCommunityScreen(evt.community))
|
||||
}
|
||||
|
||||
DrawerEvent.ManageSubscriptions -> {
|
||||
navigator?.push(ManageSubscriptionsScreen())
|
||||
navigationCoordinator.pushScreen(ManageSubscriptionsScreen())
|
||||
}
|
||||
|
||||
DrawerEvent.OpenBookmarks -> {
|
||||
navigator?.push(SavedItemsScreen())
|
||||
navigationCoordinator.pushScreen(SavedItemsScreen())
|
||||
}
|
||||
}
|
||||
}.launchIn(this)
|
||||
|
Loading…
x
Reference in New Issue
Block a user