feat: add share action to text toolbar in selection mode (#1175)

This commit is contained in:
Diego Beraldin 2024-07-28 15:31:33 +02:00 committed by GitHub
parent 2b122e49b8
commit 957bcb38ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 788 additions and 705 deletions

View File

@ -20,8 +20,10 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.dp
@ -35,7 +37,10 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ancillaryT
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.components.CustomizedContent
import com.github.diegoberaldin.raccoonforlemmy.core.l10n.messages.LocalStrings
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.share.getShareHelper
import com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar.getCustomTextToolbar
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
@ -96,151 +101,167 @@ fun CommentCard(
} else {
0.dp
}
val shareHelper = remember { getShareHelper() }
val clipboardManager = LocalClipboardManager.current
val onShareLambda =
rememberCallback {
val query = clipboardManager.getText()?.text.orEmpty()
shareHelper.share(query)
}
val shareActionLabel = LocalStrings.current.postActionShare
Column(
modifier = modifier,
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
),
) {
Box(
modifier =
Modifier
.onClick(
onClick = {
if (textSelection) {
focusManager.clearFocus()
textSelection = false
} else {
onClick?.invoke()
}
},
onDoubleClick = onDoubleClick ?: {},
).padding(
start =
indentAmount
.takeIf {
it > 0 && comment.depth > 0
}?.let {
(it * comment.depth).dp + Spacing.xxxs
} ?: 0.dp,
),
Column(
modifier = modifier,
) {
Column(
Box(
modifier =
Modifier
.padding(start = barWidth)
.fillMaxWidth()
.padding(
vertical = Spacing.xxs,
horizontal = Spacing.s,
).onGloballyPositioned {
commentHeight = it.size.toSize().height
},
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
.onClick(
onClick = {
if (textSelection) {
focusManager.clearFocus()
textSelection = false
} else {
onClick?.invoke()
}
},
onDoubleClick = onDoubleClick ?: {},
).padding(
start =
indentAmount
.takeIf {
it > 0 && comment.depth > 0
}?.let {
(it * comment.depth).dp + Spacing.xxxs
} ?: 0.dp,
),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(top = Spacing.xxs),
iconSize = IconSize.s,
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
creator = comment.creator.takeIf { !hideAuthor },
community = comment.community.takeIf { !hideCommunity },
indicatorExpanded = comment.expanded.takeIf { showExpandedIndicator },
distinguished = comment.distinguished,
isOp = isOp,
isMod = isMod,
isAdmin = isAdmin,
isBot = comment.creator?.bot.takeIf { showBot } ?: false,
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onToggleExpanded = onToggleExpanded,
)
if (comment.removed) {
Text(
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else if (comment.deleted) {
Text(
modifier = Modifier.fillMaxWidth(),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Comment) {
CompositionLocalProvider(
LocalDensity provides
Density(
density = LocalDensity.current.density,
// additional downscale for font in comments
fontScale = LocalDensity.current.fontScale * COMMENT_TEXT_SCALE_FACTOR,
),
) {
PostCardBody(
text = comment.text.orEmpty(),
autoLoadImages = autoLoadImages,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
highlightText = highlightText,
onOpenImage = onImageClick,
onDoubleClick = onDoubleClick,
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenWeb = onOpenWeb,
onLongClick = {
textSelection = true
},
)
}
}
}
PostCardFooter(
modifier = Modifier.padding(vertical = Spacing.xs),
score = comment.score,
showScores = showScores,
voteFormat = voteFormat,
upVotes = comment.upvotes,
downVotes = comment.downvotes,
saved = comment.saved,
upVoted = comment.myVote > 0,
downVoted = comment.myVote < 0,
comments = comment.comments,
actionButtonsActive = actionButtonsActive,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = comment.publishDate,
updateDate = comment.updateDate,
options = options,
onOptionSelected = onOptionSelected,
)
}
if (indentAmount > 0 && comment.depth > 0) {
Box(
Column(
modifier =
Modifier
.padding(top = Spacing.xxs)
.width(barWidth)
.height(commentHeight.toLocalDp())
.background(color = barColor, shape = RoundedCornerShape(barWidth / 2)),
)
.padding(start = barWidth)
.fillMaxWidth()
.padding(
vertical = Spacing.xxs,
horizontal = Spacing.s,
).onGloballyPositioned {
commentHeight = it.size.toSize().height
},
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(top = Spacing.xxs),
iconSize = IconSize.s,
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
creator = comment.creator.takeIf { !hideAuthor },
community = comment.community.takeIf { !hideCommunity },
indicatorExpanded = comment.expanded.takeIf { showExpandedIndicator },
distinguished = comment.distinguished,
isOp = isOp,
isMod = isMod,
isAdmin = isAdmin,
isBot = comment.creator?.bot.takeIf { showBot } ?: false,
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onToggleExpanded = onToggleExpanded,
)
if (comment.removed) {
Text(
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else if (comment.deleted) {
Text(
modifier = Modifier.fillMaxWidth(),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Comment) {
CompositionLocalProvider(
LocalDensity provides
Density(
density = LocalDensity.current.density,
// additional downscale for font in comments
fontScale = LocalDensity.current.fontScale * COMMENT_TEXT_SCALE_FACTOR,
),
) {
PostCardBody(
text = comment.text.orEmpty(),
autoLoadImages = autoLoadImages,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
highlightText = highlightText,
onOpenImage = onImageClick,
onDoubleClick = onDoubleClick,
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenWeb = onOpenWeb,
onLongClick = {
textSelection = true
},
)
}
}
}
PostCardFooter(
modifier = Modifier.padding(vertical = Spacing.xs),
score = comment.score,
showScores = showScores,
voteFormat = voteFormat,
upVotes = comment.upvotes,
downVotes = comment.downvotes,
saved = comment.saved,
upVoted = comment.myVote > 0,
downVoted = comment.myVote < 0,
comments = comment.comments,
actionButtonsActive = actionButtonsActive,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = comment.publishDate,
updateDate = comment.updateDate,
options = options,
onOptionSelected = onOptionSelected,
)
}
if (indentAmount > 0 && comment.depth > 0) {
Box(
modifier =
Modifier
.padding(top = Spacing.xxs)
.width(barWidth)
.height(commentHeight.toLocalDp())
.background(color = barColor, shape = RoundedCornerShape(barWidth / 2)),
)
}
}
}
}

View File

@ -11,6 +11,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@ -18,7 +19,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.unit.dp
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
@ -31,6 +34,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.l10n.messages.LocalStrings
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.share.getShareHelper
import com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar.getCustomTextToolbar
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PersonMentionModel
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.PostModel
@ -69,6 +74,15 @@ fun InboxCard(
rememberCallback {
onClick.invoke(mention.post)
}
val shareHelper = remember { getShareHelper() }
val clipboardManager = LocalClipboardManager.current
val onShareLambda =
rememberCallback {
val query = clipboardManager.getText()?.text.orEmpty()
shareHelper.share(query)
}
val shareActionLabel = LocalStrings.current.postActionShare
Box(
modifier =
Modifier
@ -98,99 +112,107 @@ fun InboxCard(
},
),
) {
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
),
) {
InboxCardHeader(
modifier =
Modifier
.fillMaxWidth()
Column(
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
InboxCardHeader(
modifier =
Modifier
.fillMaxWidth()
.onClick(
onClick = onClickPost,
).padding(horizontal = Spacing.s),
mention = mention,
type = type,
)
if (mention.comment.removed) {
Text(
modifier = Modifier.padding(horizontal = Spacing.s),
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
mention = mention,
type = type,
)
} else {
val previewText =
if (previewMaxLines == null || previewMaxLines < 0) {
mention.comment.text.orEmpty()
} else {
mention.comment.text
.orEmpty()
.split("\n")
.take(previewMaxLines)
.joinToString("\n")
}
CustomizedContent(ContentFontClass.Body) {
PostCardBody(
modifier =
Modifier
.fillMaxWidth()
if (mention.comment.removed) {
Text(
modifier = Modifier.padding(horizontal = Spacing.s),
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
val previewText =
if (previewMaxLines == null || previewMaxLines < 0) {
mention.comment.text.orEmpty()
} else {
mention.comment.text
.orEmpty()
.split("\n")
.take(previewMaxLines)
.joinToString("\n")
}
CustomizedContent(ContentFontClass.Body) {
PostCardBody(
modifier =
Modifier
.fillMaxWidth()
.padding(
horizontal = Spacing.s,
),
text = previewText,
autoLoadImages = autoLoadImages,
onOpenImage = onImageClick,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClickPost.invoke()
}
},
onOpenUser =
rememberCallbackArgs { user, instance ->
text = previewText,
autoLoadImages = autoLoadImages,
onOpenImage = onImageClick,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClickPost.invoke()
}
},
onOpenUser =
rememberCallbackArgs { user, instance ->
onOpenCreator(user, instance)
},
onLongClick = {
textSelection = true
},
)
onLongClick = {
textSelection = true
},
)
}
}
}
InboxReplySubtitle(
modifier =
Modifier
InboxReplySubtitle(
modifier =
Modifier
.onClick(onClick = onClickPost)
.padding(
start = Spacing.s,
end = Spacing.s,
top = Spacing.s,
),
creator = mention.creator,
community = mention.community,
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
date = mention.publishDate,
score = mention.score,
showScores = showScores,
upVotes = mention.upvotes,
downVotes = mention.downvotes,
voteFormat = voteFormat,
upVoted = mention.myVote > 0,
downVoted = mention.myVote < 0,
downVoteEnabled = downVoteEnabled,
options = options,
onOpenCommunity = onOpenCommunity,
onOpenCreator =
rememberCallbackArgs { user ->
creator = mention.creator,
community = mention.community,
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
date = mention.publishDate,
score = mention.score,
showScores = showScores,
upVotes = mention.upvotes,
downVotes = mention.downvotes,
voteFormat = voteFormat,
upVoted = mention.myVote > 0,
downVoted = mention.myVote < 0,
downVoteEnabled = downVoteEnabled,
options = options,
onOpenCommunity = onOpenCommunity,
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator(user, "")
},
onUpVote = onUpVote,
onDownVote = onDownVote,
onOptionSelected = onOptionSelected,
onReply = onReply,
)
onUpVote = onUpVote,
onDownVote = onDownVote,
onOptionSelected = onOptionSelected,
onReply = onReply,
)
}
}
}
}

View File

@ -18,6 +18,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -29,7 +30,9 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalTextToolbar
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
@ -49,6 +52,8 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallb
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
import com.github.diegoberaldin.raccoonforlemmy.core.utils.looksLikeAVideo
import com.github.diegoberaldin.raccoonforlemmy.core.utils.looksLikeAnImage
import com.github.diegoberaldin.raccoonforlemmy.core.utils.share.getShareHelper
import com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar.getCustomTextToolbar
import com.github.diegoberaldin.raccoonforlemmy.core.utils.url.getCustomTabsHelper
import com.github.diegoberaldin.raccoonforlemmy.core.utils.url.toUrlOpeningMode
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.CommunityModel
@ -230,191 +235,210 @@ private fun CompactPost(
.orEmpty()
.takeIf { !it.looksLikeAnImage && !it.looksLikeAVideo }
.orEmpty()
val shareHelper = remember { getShareHelper() }
val clipboardManager = LocalClipboardManager.current
val onShareLambda =
rememberCallback {
val query = clipboardManager.getText()?.text.orEmpty()
shareHelper.share(query)
}
val shareActionLabel = LocalStrings.current.postActionShare
Column(
modifier =
modifier
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = Spacing.xs)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
if (textSelection) {
focusManager.clearFocus()
textSelection = false
} else {
onClick?.invoke()
}
},
)
},
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(horizontal = Spacing.xs),
community = post.community,
creator = post.creator.takeIf { !hideAuthor },
featuredCommunity = post.featuredCommunity,
featuredLocal = post.featuredLocal,
locked = post.locked,
markRead = markRead,
isFromModerator = isFromModerator,
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
onDoubleClick = onDoubleClick,
)
Row(
modifier = Modifier.padding(horizontal = Spacing.xs),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(Spacing.xs),
) {
if (post.deleted) {
Text(
modifier = Modifier.fillMaxWidth(),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Title) {
PostCardTitle(
modifier = Modifier.weight(0.75f),
text = post.title,
autoLoadImages = autoLoadImages,
markRead = markRead,
highlightText = highlightText,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenImage = onOpenImage,
onDoubleClick = onDoubleClick,
onOpenWeb = onOpenWeb,
onLongClick = {
textSelection = true
},
)
}
if (post.videoUrl.isNotEmpty()) {
PostCardVideo(
modifier =
Modifier
.weight(0.25f)
.padding(vertical = Spacing.xxs),
url = post.videoUrl,
blurred = blurNsfw && post.nsfw,
autoLoadImages = autoLoadImages,
onOpen =
rememberCallback {
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
Column(
modifier =
modifier
.background(MaterialTheme.colorScheme.background)
.padding(horizontal = Spacing.xs)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
if (textSelection) {
focusManager.clearFocus()
textSelection = false
} else {
onClick?.invoke()
}
},
)
},
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(horizontal = Spacing.xs),
community = post.community,
creator = post.creator.takeIf { !hideAuthor },
featuredCommunity = post.featuredCommunity,
featuredLocal = post.featuredLocal,
locked = post.locked,
markRead = markRead,
isFromModerator = isFromModerator,
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
onDoubleClick = onDoubleClick,
)
Row(
modifier = Modifier.padding(horizontal = Spacing.xs),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(Spacing.xs),
) {
if (post.deleted) {
Text(
modifier = Modifier.fillMaxWidth(),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
PostCardImage(
modifier =
Modifier
.weight(0.25f)
.then(
if (fullHeightImage) {
Modifier
} else {
Modifier.aspectRatio(1f)
},
).padding(vertical = Spacing.xs)
.clip(RoundedCornerShape(CornerSize.s)),
minHeight = Dp.Unspecified,
maxHeight = Dp.Unspecified,
imageUrl = post.imageUrl,
autoLoadImages = autoLoadImages,
loadButtonContent = @Composable {
Icon(imageVector = Icons.Default.Download, contentDescription = null)
},
blurred = blurNsfw && post.nsfw,
onImageClick =
rememberCallbackArgs { url ->
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
CustomizedContent(ContentFontClass.Title) {
PostCardTitle(
modifier = Modifier.weight(0.75f),
text = post.title,
autoLoadImages = autoLoadImages,
markRead = markRead,
highlightText = highlightText,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onOpenImage?.invoke(url)
onClick?.invoke()
}
},
onDoubleClick = onDoubleClick,
)
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenImage = onOpenImage,
onDoubleClick = onDoubleClick,
onOpenWeb = onOpenWeb,
onLongClick = {
textSelection = true
},
)
}
if (post.videoUrl.isNotEmpty()) {
PostCardVideo(
modifier =
Modifier
.weight(0.25f)
.padding(vertical = Spacing.xxs),
url = post.videoUrl,
blurred = blurNsfw && post.nsfw,
autoLoadImages = autoLoadImages,
onOpen =
rememberCallback {
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
} else {
onClick?.invoke()
}
},
)
} else {
PostCardImage(
modifier =
Modifier
.weight(0.25f)
.then(
if (fullHeightImage) {
Modifier
} else {
Modifier.aspectRatio(1f)
},
).padding(vertical = Spacing.xs)
.clip(RoundedCornerShape(CornerSize.s)),
minHeight = Dp.Unspecified,
maxHeight = Dp.Unspecified,
imageUrl = post.imageUrl,
autoLoadImages = autoLoadImages,
loadButtonContent = @Composable {
Icon(
imageVector = Icons.Default.Download,
contentDescription = null,
)
},
blurred = blurNsfw && post.nsfw,
onImageClick =
rememberCallbackArgs { url ->
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
} else {
onOpenImage?.invoke(url)
}
},
onDoubleClick = onDoubleClick,
)
}
}
}
PostCardFooter(
modifier =
Modifier.padding(
top = Spacing.xxs,
start = Spacing.xs,
end = Spacing.xs,
),
markRead = markRead,
comments = post.comments,
voteFormat = voteFormat,
score = post.score,
showScores = showScores,
unreadComments =
post.unreadComments.takeIf {
it != null && it > 0 && showUnreadComments && it != post.comments
},
upVotes = post.upvotes,
downVotes = post.downvotes,
upVoted = post.myVote > 0,
downVoted = post.myVote < 0,
saved = post.saved,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = post.publishDate,
updateDate = post.updateDate,
options = options,
onOptionSelected = onOptionSelected,
actionButtonsActive = actionButtonsActive,
)
}
PostCardFooter(
modifier =
Modifier.padding(
top = Spacing.xxs,
start = Spacing.xs,
end = Spacing.xs,
),
markRead = markRead,
comments = post.comments,
voteFormat = voteFormat,
score = post.score,
showScores = showScores,
unreadComments =
post.unreadComments.takeIf {
it != null && it > 0 && showUnreadComments && it != post.comments
},
upVotes = post.upvotes,
downVotes = post.downvotes,
upVoted = post.myVote > 0,
downVoted = post.myVote < 0,
saved = post.saved,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = post.publishDate,
updateDate = post.updateDate,
options = options,
onOptionSelected = onOptionSelected,
actionButtonsActive = actionButtonsActive,
)
}
}
@ -470,144 +494,119 @@ private fun ExtendedPost(
!it.looksLikeAnImage &&
!it.looksLikeAVideo
}.orEmpty()
val shareHelper = remember { getShareHelper() }
val clipboardManager = LocalClipboardManager.current
val onShareLambda =
rememberCallback {
val query = clipboardManager.getText()?.text.orEmpty()
shareHelper.share(query)
}
val shareActionLabel = LocalStrings.current.postActionShare
Column(
modifier =
modifier
.background(backgroundColor)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
),
) {
Column(
modifier =
modifier
.background(backgroundColor)
.pointerInput(Unit) {
detectTapGestures(
onTap = {
if (textSelection) {
textSelection = false
} else {
onClick?.invoke()
}
},
)
},
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(horizontal = Spacing.s),
community = post.community,
creator = post.creator.takeIf { !hideAuthor },
featuredCommunity = post.featuredCommunity,
featuredLocal = post.featuredLocal,
locked = post.locked,
markRead = markRead,
isFromModerator = isFromModerator,
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
onDoubleClick = onDoubleClick,
)
if (post.deleted) {
Text(
modifier =
Modifier.fillMaxWidth().padding(
all = Spacing.s,
),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Title) {
PostCardTitle(
modifier =
Modifier
.fillMaxWidth()
.padding(
vertical = Spacing.xs,
horizontal = Spacing.s,
),
text = post.title,
markRead = markRead,
highlightText = highlightText,
bolder = showBody,
autoLoadImages = autoLoadImages,
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenWeb = onOpenWeb,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
onOpenImage = onOpenImage,
onDoubleClick = onDoubleClick,
onLongClick = {
textSelection = true
},
)
},
verticalArrangement = Arrangement.spacedBy(Spacing.xxs),
) {
CommunityAndCreatorInfo(
modifier = Modifier.padding(horizontal = Spacing.s),
community = post.community,
creator = post.creator.takeIf { !hideAuthor },
featuredCommunity = post.featuredCommunity,
featuredLocal = post.featuredLocal,
locked = post.locked,
markRead = markRead,
isFromModerator = isFromModerator,
onOpenCommunity =
rememberCallbackArgs { community ->
onOpenCommunity?.invoke(community, "")
},
onOpenCreator =
rememberCallbackArgs { user ->
onOpenCreator?.invoke(user, "")
},
autoLoadImages = autoLoadImages,
preferNicknames = preferNicknames,
onDoubleClick = onDoubleClick,
)
if (post.deleted) {
Text(
modifier =
Modifier.fillMaxWidth().padding(
all = Spacing.s,
),
text = LocalStrings.current.messageContentDeleted,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Title) {
PostCardTitle(
modifier =
Modifier
.fillMaxWidth()
.padding(
vertical = Spacing.xs,
horizontal = Spacing.s,
),
text = post.title,
markRead = markRead,
highlightText = highlightText,
bolder = showBody,
autoLoadImages = autoLoadImages,
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenWeb = onOpenWeb,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
onOpenImage = onOpenImage,
onDoubleClick = onDoubleClick,
onLongClick = {
textSelection = true
},
)
}
}
if (post.videoUrl.isNotEmpty()) {
PostCardVideo(
modifier =
Modifier
.padding(
vertical = Spacing.xxs,
horizontal = if (fullWidthImage) 0.dp else Spacing.s,
),
url = post.videoUrl,
blurred = blurNsfw && post.nsfw,
autoLoadImages = autoLoadImages,
backgroundColor = backgroundColor,
onOpen = {
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
} else {
onClick?.invoke()
}
},
)
} else {
PostCardImage(
modifier =
Modifier
.padding(
vertical = Spacing.xs,
horizontal = if (fullWidthImage) 0.dp else Spacing.s,
).then(
if (roundedCornerImage && !fullWidthImage) {
Modifier.clip(RoundedCornerShape(CornerSize.xl))
} else {
Modifier
},
).then(
if (fullHeightImage) {
Modifier
} else {
Modifier.heightIn(max = 200.dp)
},
),
imageUrl = post.imageUrl,
blurred = blurNsfw && post.nsfw,
onImageClick =
rememberCallbackArgs { url ->
if (post.videoUrl.isNotEmpty()) {
PostCardVideo(
modifier =
Modifier
.padding(
vertical = Spacing.xxs,
horizontal = if (fullWidthImage) 0.dp else Spacing.s,
),
url = post.videoUrl,
blurred = blurNsfw && post.nsfw,
autoLoadImages = autoLoadImages,
backgroundColor = backgroundColor,
onOpen = {
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
@ -620,75 +619,35 @@ private fun ExtendedPost(
onOpenUser = onOpenCreator,
)
} else {
onOpenImage?.invoke(url)
onClick?.invoke()
}
},
onDoubleClick = onDoubleClick,
autoLoadImages = autoLoadImages,
)
}
if (showBody) {
if (post.removed) {
Text(
modifier = Modifier.padding(horizontal = Spacing.s),
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Body) {
PostCardBody(
modifier =
Modifier
.fillMaxWidth()
.padding(
top = Spacing.xxs,
start = Spacing.s,
end = Spacing.s,
),
text = post.text,
maxLines =
if (limitBodyHeight) {
settings.postBodyMaxLines
} else {
null
},
autoLoadImages = autoLoadImages,
markRead = markRead,
highlightText = highlightText,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenImage = onOpenImage,
onOpenWeb = onOpenWeb,
onDoubleClick = onDoubleClick,
onLongClick = {
textSelection = true
},
)
}
}
}
if (postLinkUrl.isNotEmpty()) {
PostLinkBanner(
modifier =
Modifier
.padding(
top = Spacing.s,
bottom = Spacing.xxs,
start = Spacing.s,
end = Spacing.s,
).onClick(
onClick = {
PostCardImage(
modifier =
Modifier
.padding(
vertical = Spacing.xs,
horizontal = if (fullWidthImage) 0.dp else Spacing.s,
).then(
if (roundedCornerImage && !fullWidthImage) {
Modifier.clip(RoundedCornerShape(CornerSize.xl))
} else {
Modifier
},
).then(
if (fullHeightImage) {
Modifier
} else {
Modifier.heightIn(max = 200.dp)
},
),
imageUrl = post.imageUrl,
blurred = blurNsfw && post.nsfw,
onImageClick =
rememberCallbackArgs { url ->
if (postLinkUrl.isNotEmpty() && settings.openPostWebPageOnImageClick) {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
@ -699,45 +658,126 @@ private fun ExtendedPost(
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
} else {
onOpenImage?.invoke(url)
}
},
onDoubleClick = onDoubleClick,
autoLoadImages = autoLoadImages,
)
}
if (showBody) {
if (post.removed) {
Text(
modifier = Modifier.padding(horizontal = Spacing.s),
text = LocalStrings.current.messageContentRemoved,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ancillaryTextAlpha),
)
} else {
CustomizedContent(ContentFontClass.Body) {
PostCardBody(
modifier =
Modifier
.fillMaxWidth()
.padding(
top = Spacing.xxs,
start = Spacing.s,
end = Spacing.s,
),
text = post.text,
maxLines =
if (limitBodyHeight) {
settings.postBodyMaxLines
} else {
null
},
autoLoadImages = autoLoadImages,
markRead = markRead,
highlightText = highlightText,
onClick = {
if (textSelection) {
focusManager.clearFocus(true)
textSelection = false
} else {
onClick?.invoke()
}
},
onDoubleClick = onDoubleClick ?: {},
),
url = postLinkUrl,
)
onOpenCommunity = onOpenCommunity,
onOpenUser = onOpenCreator,
onOpenPost = onOpenPost,
onOpenImage = onOpenImage,
onOpenWeb = onOpenWeb,
onDoubleClick = onDoubleClick,
onLongClick = {
textSelection = true
},
)
}
}
}
if (postLinkUrl.isNotEmpty()) {
PostLinkBanner(
modifier =
Modifier
.padding(
top = Spacing.s,
bottom = Spacing.xxs,
start = Spacing.s,
end = Spacing.s,
).onClick(
onClick = {
navigationCoordinator.handleUrl(
url = postLinkUrl,
openingMode = settings.urlOpeningMode.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenWeb = onOpenWeb,
onOpenCommunity = onOpenCommunity,
onOpenPost = onOpenPost,
onOpenUser = onOpenCreator,
)
},
onDoubleClick = onDoubleClick ?: {},
),
url = postLinkUrl,
)
}
}
PostCardFooter(
modifier =
Modifier.padding(
top = Spacing.xs,
start = Spacing.s,
end = Spacing.s,
),
markRead = markRead,
comments = post.comments,
voteFormat = voteFormat,
score = post.score,
showScores = showScores,
unreadComments =
post.unreadComments.takeIf {
it != null && it > 0 && showUnreadComments && it != post.comments
},
upVotes = post.upvotes,
downVotes = post.downvotes,
upVoted = post.myVote > 0,
downVoted = post.myVote < 0,
saved = post.saved,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = post.publishDate,
updateDate = post.updateDate,
options = options,
onOptionSelected = onOptionSelected,
actionButtonsActive = actionButtonsActive,
)
}
PostCardFooter(
modifier =
Modifier.padding(
top = Spacing.xs,
start = Spacing.s,
end = Spacing.s,
),
markRead = markRead,
comments = post.comments,
voteFormat = voteFormat,
score = post.score,
showScores = showScores,
unreadComments =
post.unreadComments.takeIf {
it != null && it > 0 && showUnreadComments && it != post.comments
},
upVotes = post.upvotes,
downVotes = post.downvotes,
upVoted = post.myVote > 0,
downVoted = post.myVote < 0,
saved = post.saved,
downVoteEnabled = downVoteEnabled,
onClick = onClick,
onUpVote = onUpVote,
onDownVote = onDownVote,
onSave = onSave,
onReply = onReply,
publishDate = post.publishDate,
updateDate = post.updateDate,
options = options,
onOptionSelected = onOptionSelected,
actionButtonsActive = actionButtonsActive,
)
}
}

View File

@ -69,6 +69,7 @@ fun PostCardTitle(
val enableAlternateMarkdownRendering by settingsRepository.currentSettings
.map { it.enableAlternateMarkdownRendering }
.collectAsState(false)
SelectionContainer {
CustomMarkdownWrapper(
modifier = modifier.padding(horizontal = Spacing.xxs),
@ -103,7 +104,9 @@ fun PostCardTitle(
rememberCallbackArgs { url ->
navigationCoordinator.handleUrl(
url = url,
openingMode = settingsRepository.currentSettings.value.urlOpeningMode.toUrlOpeningMode(),
openingMode =
settingsRepository.currentSettings.value.urlOpeningMode
.toUrlOpeningMode(),
uriHandler = uriHandler,
customTabsHelper = customTabsHelper,
onOpenCommunity = onOpenCommunity,

View File

@ -1,89 +1,30 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent
package com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar
import android.view.ActionMode
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.platform.TextToolbar
import androidx.compose.ui.platform.TextToolbarStatus
private const val ACTION_ID_COPY = 0
private const val ACTION_ID_SEARCH = 1
private const val ACTION_ID_QUOTE = 2
private const val GROUP_ID = 0
class CustomTextToolbar(
private val view: View,
private val isLogged: Boolean,
private val quoteActionLabel: String,
private val shareActionLabel: String,
private val onShare: () -> Unit,
private val onQuote: () -> Unit,
) : TextToolbar {
private var actionMode: ActionMode? = null
override var status: TextToolbarStatus = TextToolbarStatus.Hidden
private set
override fun hide() {
status = TextToolbarStatus.Hidden
actionMode?.finish()
actionMode = null
}
override fun showMenu(
rect: Rect,
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?,
) {
if (actionMode == null) {
status = TextToolbarStatus.Shown
actionMode =
view.startActionMode(
CustomTextActionModeCallback(
rect = rect,
isLogged = isLogged,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
onCopy = {
onCopyRequested?.invoke()
},
onShare = {
onCopyRequested?.invoke()
onShare()
},
onQuote = {
onCopyRequested?.invoke()
onQuote()
},
),
ActionMode.TYPE_FLOATING,
)
} else {
actionMode?.invalidate()
actionMode = null
}
}
}
private class CustomTextActionModeCallback(
internal class CustomTextActionModeCallback(
private val rect: Rect,
private val quoteActionLabel: String,
private val quoteActionLabel: String?,
private val shareActionLabel: String,
private val isLogged: Boolean,
private val onCopy: () -> Unit,
private val onShare: () -> Unit,
private val onQuote: () -> Unit,
private val onQuote: (() -> Unit)?,
) : ActionMode.Callback2() {
override fun onCreateActionMode(
mode: ActionMode?,
menu: Menu?,
): Boolean {
menu?.apply {
if (isLogged) {
if (quoteActionLabel != null) {
add(
GROUP_ID,
ACTION_ID_QUOTE,
@ -129,7 +70,7 @@ private class CustomTextActionModeCallback(
}
ACTION_ID_QUOTE -> {
onQuote()
onQuote?.invoke()
true
}

View File

@ -0,0 +1,61 @@
package com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar
import android.view.ActionMode
import android.view.View
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.platform.TextToolbar
import androidx.compose.ui.platform.TextToolbarStatus
internal class CustomTextToolbar(
private val view: View,
private val quoteActionLabel: String?,
private val shareActionLabel: String,
private val onShare: () -> Unit,
private val onQuote: (() -> Unit)?,
) : TextToolbar {
private var actionMode: ActionMode? = null
override var status: TextToolbarStatus = TextToolbarStatus.Hidden
private set
override fun hide() {
status = TextToolbarStatus.Hidden
actionMode?.finish()
actionMode = null
}
override fun showMenu(
rect: Rect,
onCopyRequested: (() -> Unit)?,
onPasteRequested: (() -> Unit)?,
onCutRequested: (() -> Unit)?,
onSelectAllRequested: (() -> Unit)?,
) {
if (actionMode == null) {
status = TextToolbarStatus.Shown
actionMode =
view.startActionMode(
CustomTextActionModeCallback(
rect = rect,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
onCopy = {
onCopyRequested?.invoke()
},
onShare = {
onCopyRequested?.invoke()
onShare()
},
onQuote = {
onCopyRequested?.invoke()
onQuote?.invoke()
},
),
ActionMode.TYPE_FLOATING,
)
} else {
actionMode?.invalidate()
actionMode = null
}
}
}

View File

@ -1,24 +1,20 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.di
package com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.TextToolbar
import com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.CustomTextToolbar
@Composable
actual fun getCustomTextToolbar(
isLogged: Boolean,
quoteActionLabel: String,
quoteActionLabel: String?,
shareActionLabel: String,
onShare: () -> Unit,
onQuote: () -> Unit,
): TextToolbar {
return CustomTextToolbar(
onQuote: (() -> Unit)?,
): TextToolbar =
CustomTextToolbar(
view = LocalView.current,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
isLogged = isLogged,
onShare = onShare,
onQuote = onQuote,
)
}

View File

@ -1,13 +1,12 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.di
package com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.TextToolbar
@Composable
expect fun getCustomTextToolbar(
isLogged: Boolean,
quoteActionLabel: String,
quoteActionLabel: String? = null,
shareActionLabel: String,
onShare: () -> Unit,
onQuote: () -> Unit,
onQuote: (() -> Unit)? = null,
): TextToolbar

View File

@ -1,4 +1,4 @@
package com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.di
package com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalTextToolbar
@ -6,11 +6,8 @@ import androidx.compose.ui.platform.TextToolbar
@Composable
actual fun getCustomTextToolbar(
isLogged: Boolean,
quoteActionLabel: String,
quoteActionLabel: String?,
shareActionLabel: String,
onShare: () -> Unit,
onQuote: () -> Unit,
): TextToolbar {
return LocalTextToolbar.current
}
onQuote: (() -> Unit)?,
): TextToolbar = LocalTextToolbar.current

View File

@ -38,7 +38,7 @@ import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.l10n.messages.LocalStrings
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
import com.github.diegoberaldin.raccoonforlemmy.core.utils.share.getShareHelper
import com.github.diegoberaldin.raccoonforlemmy.unit.rawcontent.di.getCustomTextToolbar
import com.github.diegoberaldin.raccoonforlemmy.core.utils.texttoolbar.getCustomTextToolbar
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -66,7 +66,12 @@ fun RawContentDialog(
val query = clipboardManager.getText()?.text.orEmpty()
onQuote?.invoke(query)
}
val quoteActionLabel = LocalStrings.current.actionQuote
val quoteActionLabel =
if (isLogged) {
LocalStrings.current.actionQuote
} else {
null
}
val shareActionLabel = LocalStrings.current.postActionShare
val fullColor = MaterialTheme.colorScheme.onBackground
@ -75,7 +80,8 @@ fun RawContentDialog(
) {
Column(
modifier =
Modifier.background(color = MaterialTheme.colorScheme.surface)
Modifier
.background(color = MaterialTheme.colorScheme.surface)
.padding(vertical = Spacing.s),
horizontalAlignment = Alignment.CenterHorizontally,
) {
@ -104,7 +110,6 @@ fun RawContentDialog(
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
isLogged = isLogged,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
@ -138,7 +143,6 @@ fun RawContentDialog(
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
isLogged = isLogged,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
onShare = onShareLambda,
@ -173,7 +177,6 @@ fun RawContentDialog(
CompositionLocalProvider(
LocalTextToolbar provides
getCustomTextToolbar(
isLogged = isLogged,
quoteActionLabel = quoteActionLabel,
shareActionLabel = shareActionLabel,
onShare = onShareLambda,