Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace all relevant dialogs with Animated Center Popup menus #1200

Merged
merged 14 commits into from
Sep 4, 2023
88 changes: 0 additions & 88 deletions app/src/main/java/com/jerboa/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,21 @@ import androidx.activity.result.contract.ActivityResultContract
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatDelegate
import androidx.browser.customtabs.CustomTabsIntent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.pager.PagerState
import androidx.compose.material3.DrawerState
import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.TabPosition
import androidx.compose.runtime.Stable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.autofill.Autofill
import androidx.compose.ui.autofill.AutofillNode
import androidx.compose.ui.autofill.AutofillTree
import androidx.compose.ui.autofill.AutofillType
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.lerp
import androidx.core.os.LocaleListCompat
import androidx.core.util.PatternsCompat
import androidx.lifecycle.LiveData
Expand Down Expand Up @@ -870,52 +856,6 @@ enum class PostType {
}
}

@OptIn(ExperimentalFoundationApi::class)
fun Modifier.pagerTabIndicatorOffset2(
pagerState: PagerState,
tabPositions: List<TabPosition>,
pageIndexMapping: (Int) -> Int = { it },
): Modifier = layout { measurable, constraints ->
if (tabPositions.isEmpty()) {
// If there are no pages, nothing to show
layout(constraints.maxWidth, 0) {}
} else {
val currentPage = minOf(tabPositions.lastIndex, pageIndexMapping(pagerState.currentPage))
val currentTab = tabPositions[currentPage]
val previousTab = tabPositions.getOrNull(currentPage - 1)
val nextTab = tabPositions.getOrNull(currentPage + 1)
val fraction = pagerState.currentPageOffsetFraction
val indicatorWidth = if (fraction > 0 && nextTab != null) {
lerp(currentTab.width, nextTab.width, fraction).roundToPx()
} else if (fraction < 0 && previousTab != null) {
lerp(currentTab.width, previousTab.width, -fraction).roundToPx()
} else {
currentTab.width.roundToPx()
}
val indicatorOffset = if (fraction > 0 && nextTab != null) {
lerp(currentTab.left, nextTab.left, fraction).roundToPx()
} else if (fraction < 0 && previousTab != null) {
lerp(currentTab.left, previousTab.left, -fraction).roundToPx()
} else {
currentTab.left.roundToPx()
}
val placeable = measurable.measure(
Constraints(
minWidth = indicatorWidth,
maxWidth = indicatorWidth,
minHeight = 0,
maxHeight = constraints.maxHeight,
),
)
layout(constraints.maxWidth, maxOf(placeable.height, constraints.minHeight)) {
placeable.placeRelative(
indicatorOffset,
maxOf(constraints.minHeight - placeable.height, 0),
)
}
}
}

fun isSameInstance(url: String, instance: String): Boolean {
return hostName(url) == instance
}
Expand Down Expand Up @@ -1006,34 +946,6 @@ fun saveMediaP(
MediaScannerConnection.scanFile(context, arrayOf(dest.absolutePath), mimeTypes, null)
}

@OptIn(ExperimentalComposeUiApi::class)
fun Modifier.onAutofill(
tree: AutofillTree,
autofill: Autofill?,
autofillTypes: ImmutableList<AutofillType>,
onFill: (String) -> Unit,
): Modifier {
val autofillNode = AutofillNode(
autofillTypes = autofillTypes,
onFill = onFill,
)
tree += autofillNode

return this
.onGloballyPositioned {
autofillNode.boundingBox = it.boundsInWindow()
}
.onFocusChanged { focusState ->
autofill?.run {
if (focusState.isFocused) {
requestAutofillForNode(autofillNode)
} else {
cancelAutofillForNode(autofillNode)
}
}
}
}

/**
* Converts a scalable pixel (sp) to an actual pixel (px)
*/
Expand Down
8 changes: 4 additions & 4 deletions app/src/main/java/com/jerboa/datatypes/types/Others.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ enum class RegistrationMode {
enum class SortType(
@StringRes val shortForm: Int,
@StringRes val longForm: Int,
val icon: ImageVector? = null,
val icon: ImageVector,
val version: String = MINIMUM_API_VERSION,
) {
/**
Expand Down Expand Up @@ -225,14 +225,14 @@ enum class SortType(
;

companion object {
val getSupportedSortTypes = { siteVersion: String -> values().filter { compareVersions(siteVersion, it.version) >= 0 } }
val getSupportedSortTypes = { siteVersion: String -> entries.filter { compareVersions(siteVersion, it.version) >= 0 } }
}
}

/**
* Different comment sort types used in lemmy.
*/
enum class CommentSortType(val text: Int, val icon: ImageVector? = null, val version: String = MINIMUM_API_VERSION) {
enum class CommentSortType(val text: Int, val icon: ImageVector, val version: String = MINIMUM_API_VERSION) {
/**
* Comments sorted by a decaying rank.
*/
Expand Down Expand Up @@ -265,7 +265,7 @@ enum class CommentSortType(val text: Int, val icon: ImageVector? = null, val ver
;

companion object {
val getSupportedSortTypes = { siteVersion: String -> values().filter { compareVersions(siteVersion, it.version) >= 0 } }
val getSupportedSortTypes = { siteVersion: String -> entries.filter { compareVersions(siteVersion, it.version) >= 0 } }
}
}

Expand Down
178 changes: 8 additions & 170 deletions app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.jerboa.ui.components.comment

import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
Expand All @@ -20,20 +19,10 @@ import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bookmark
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.BookmarkBorder
import androidx.compose.material.icons.outlined.Comment
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Description
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material.icons.outlined.Flag
import androidx.compose.material.icons.outlined.Forum
import androidx.compose.material.icons.outlined.Link
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material.icons.outlined.Restore
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Divider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedButton
Expand All @@ -47,10 +36,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
Expand All @@ -63,7 +50,6 @@ import com.jerboa.border
import com.jerboa.buildCommentsTree
import com.jerboa.calculateCommentOffset
import com.jerboa.calculateNewInstantScores
import com.jerboa.copyToClipboard
import com.jerboa.datatypes.sampleCommentView
import com.jerboa.datatypes.sampleCommunity
import com.jerboa.datatypes.samplePost
Expand All @@ -75,7 +61,6 @@ import com.jerboa.db.entity.AnonAccount
import com.jerboa.isPostCreator
import com.jerboa.ui.components.common.ActionBarButton
import com.jerboa.ui.components.common.CommentOrPostNodeHeader
import com.jerboa.ui.components.common.IconAndTextDrawerItem
import com.jerboa.ui.components.common.MarkdownHelper
import com.jerboa.ui.components.common.MyMarkdownText
import com.jerboa.ui.components.common.VoteGeneric
Expand Down Expand Up @@ -545,37 +530,16 @@ fun CommentFooterLine(
var showMoreOptions by remember { mutableStateOf(false) }

if (showMoreOptions) {
CommentOptionsDialog(
CommentOptionsDropdown(
commentView = commentView,
onDismissRequest = { showMoreOptions = false },
onViewSourceClick = {
showMoreOptions = false
onViewSourceClick()
},
onEditCommentClick = {
showMoreOptions = false
onEditCommentClick(commentView)
},
onDeleteCommentClick = {
showMoreOptions = false
onDeleteCommentClick(commentView)
},
onReportClick = {
showMoreOptions = false
onReportClick(commentView)
},
onBlockCreatorClick = {
showMoreOptions = false
onBlockCreatorClick(commentView.creator)
},
onCommentLinkClick = {
showMoreOptions = false
onCommentLinkClick(commentView)
},
onPersonClick = {
showMoreOptions = false
onPersonClick(commentView.creator.id)
},
onViewSourceClick = onViewSourceClick,
onEditCommentClick = onEditCommentClick,
onDeleteCommentClick = onDeleteCommentClick,
onReportClick = onReportClick,
onBlockCreatorClick = onBlockCreatorClick,
onCommentLinkClick = onCommentLinkClick,
onPersonClick = onPersonClick,
isCreator = account.id == commentView.creator.id,
viewSource = viewSource,
)
Expand Down Expand Up @@ -696,132 +660,6 @@ fun CommentNodesPreview() {
)
}

@Composable
fun CommentOptionsDialog(
onDismissRequest: () -> Unit,
onViewSourceClick: () -> Unit,
onEditCommentClick: () -> Unit,
onDeleteCommentClick: () -> Unit,
onReportClick: () -> Unit,
onBlockCreatorClick: () -> Unit,
onCommentLinkClick: () -> Unit,
onPersonClick: () -> Unit,
isCreator: Boolean,
commentView: CommentView,
viewSource: Boolean,
) {
val localClipboardManager = LocalClipboardManager.current
val ctx = LocalContext.current

AlertDialog(
onDismissRequest = onDismissRequest,
text = {
Column {
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_goto_comment),
icon = Icons.Outlined.Forum,
onClick = onCommentLinkClick,
)
IconAndTextDrawerItem(
text = stringResource(
R.string.comment_node_go_to,
commentView.creator.name,
),
icon = Icons.Outlined.Person,
onClick = onPersonClick,
)
IconAndTextDrawerItem(
text = if (viewSource) {
stringResource(R.string.comment_node_view_original)
} else {
stringResource(R.string.comment_node_view_source)
},
icon = Icons.Outlined.Description,
onClick = onViewSourceClick,
)
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_copy_permalink),
icon = Icons.Outlined.Link,
onClick = {
val permalink = commentView.comment.ap_id
localClipboardManager.setText(AnnotatedString(permalink))
Toast.makeText(
ctx,
ctx.getString(R.string.comment_node_permalink_copied),
Toast.LENGTH_SHORT,
).show()
onDismissRequest()
},
)
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_copy_comment),
icon = Icons.Outlined.ContentCopy,
onClick = {
if (copyToClipboard(ctx, commentView.comment.content, "comment")) {
Toast.makeText(ctx, ctx.getString(R.string.comment_node_comment_copied), Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(ctx, ctx.getString(R.string.generic_error), Toast.LENGTH_SHORT).show()
}
onDismissRequest()
},
)
if (!isCreator) {
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_report_comment),
icon = Icons.Outlined.Flag,
onClick = onReportClick,
)
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_block, commentView.creator.name),
icon = Icons.Outlined.Block,
onClick = onBlockCreatorClick,
)
}
if (isCreator) {
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_edit),
icon = Icons.Outlined.Edit,
onClick = onEditCommentClick,
)
val deleted = commentView.comment.deleted
if (deleted) {
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_restore),
icon = Icons.Outlined.Restore,
onClick = onDeleteCommentClick,
)
} else {
IconAndTextDrawerItem(
text = stringResource(R.string.comment_node_delete),
icon = Icons.Outlined.Delete,
onClick = onDeleteCommentClick,
)
}
}
}
},
confirmButton = {},
)
}

@Preview
@Composable
fun CommentOptionsDialogPreview() {
CommentOptionsDialog(
isCreator = true,
commentView = sampleCommentView,
onDismissRequest = {},
onEditCommentClick = {},
onDeleteCommentClick = {},
onReportClick = {},
onViewSourceClick = {},
onCommentLinkClick = {},
onPersonClick = {},
onBlockCreatorClick = {},
viewSource = false,
)
}

@Composable
fun ShowMoreChildren(
commentView: CommentView,
Expand Down
Loading