mirror of
https://github.com/LiveFastEatTrashRaccoon/RaccoonForLemmy.git
synced 2025-02-08 20:38:41 +01:00
feat: add share action to text toolbar in selection mode (#1175)
This commit is contained in:
parent
2b122e49b8
commit
957bcb38ec
@ -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)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
)
|
||||
}
|
@ -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
|
@ -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
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user