feat: Tooltip{component}.kt

This commit is contained in:
Pun Butrach
2025-07-11 16:04:05 +07:00
parent 1510aa58f2
commit 438fa485bd
22 changed files with 671 additions and 355 deletions

View File

@@ -6,7 +6,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
@@ -22,6 +21,7 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.revanced.manager.R
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -69,13 +69,12 @@ fun AppTopBar(
scrollBehavior = scrollBehavior,
navigationIcon = {
if (onBackClick != null) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onBackClick,
tooltip = stringResource(R.string.back),
) {
IconButton(onClick = onBackClick) {
backIcon()
}
backIcon()
}
}
},
@@ -113,13 +112,12 @@ fun AppTopBar(
scrollBehavior = scrollBehavior,
navigationIcon = {
if (onBackClick != null) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onBackClick,
tooltip = stringResource(R.string.back),
) {
IconButton(onClick = onBackClick) {
backIcon()
}
backIcon()
}
}
},

View File

@@ -4,13 +4,13 @@ import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.res.stringResource
import app.revanced.manager.R
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@Composable
fun ArrowButton(
@@ -27,19 +27,18 @@ fun ArrowButton(
)
onClick?.let {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = it,
tooltip = stringResource(description),
) {
IconButton(onClick = it) {
Icon(
imageVector = Icons.Filled.KeyboardArrowUp,
contentDescription = stringResource(description),
modifier = Modifier
.rotate(rotation)
.then(modifier)
)
}
Icon(
imageVector = Icons.Filled.KeyboardArrowUp,
contentDescription = stringResource(description),
modifier = Modifier
.rotate(rotation)
.then(modifier)
)
}
} ?: Icon(
imageVector = Icons.Filled.KeyboardArrowUp,

View File

@@ -9,7 +9,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -18,6 +17,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import app.revanced.manager.R
import app.revanced.manager.ui.component.bundle.BundleTopBar
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -30,39 +30,36 @@ fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
Scaffold(
topBar = {
BundleTopBar(
title = stringResource(R.string.bundle_error),
title = stringResource(R.string.share),
onBackClick = onDismiss,
backIcon = {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
stringResource(R.string.back)
Icons.Outlined.Share,
contentDescription = stringResource(R.string.share)
)
},
actions = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.share),
) {
IconButton(
onClick = {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
text
)
type = "text/plain"
}
val shareIntent = Intent.createChooser(sendIntent, null)
context.startActivity(shareIntent)
onClick = {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_TEXT,
text
)
type = "text/plain"
}
) {
Icon(
Icons.Outlined.Share,
contentDescription = stringResource(R.string.share)
)
}
val shareIntent = Intent.createChooser(sendIntent, null)
context.startActivity(shareIntent)
},
tooltip = stringResource(R.string.refresh),
) {
Icon(
Icons.Outlined.Share,
stringResource(R.string.share)
)
}
}
)

View File

@@ -14,7 +14,6 @@ import androidx.compose.material.icons.outlined.Close
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -25,6 +24,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.revanced.manager.R
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@Composable
fun NotificationCard(
@@ -138,17 +138,16 @@ fun NotificationCard(
)
}
if (onDismiss != null) {
TooltipWrap(
TooltipIconButton(
modifier = modifier,
onClick = onDismiss,
tooltip = stringResource(R.string.close),
) {
IconButton(onClick = onDismiss) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.close),
tint = color,
)
}
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(R.string.close),
tint = color,
)
}
}
}

View File

@@ -5,7 +5,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Visibility
import androidx.compose.material.icons.outlined.VisibilityOff
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -19,6 +18,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import app.revanced.manager.R
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@Composable
fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (String) -> Unit, label: @Composable (() -> Unit)? = null, placeholder: @Composable (() -> Unit)? = null) {
@@ -33,18 +33,19 @@ fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (
label = label,
modifier = modifier,
trailingIcon = {
TooltipWrap(
modifier = modifier,
tooltip = if (visible) stringResource(R.string.show_password_field) else stringResource(R.string.hide_password_field),
) {
IconButton(onClick = {
TooltipIconButton(
modifier = Modifier,
onClick = {
visible = !visible
}) {
val (icon, description) = remember(visible) {
if (visible) Icons.Outlined.VisibilityOff to R.string.hide_password_field else Icons.Outlined.Visibility to R.string.show_password_field
}
Icon(icon, stringResource(description))
},
tooltip = if (visible) stringResource(R.string.show_password_field) else stringResource(
R.string.hide_password_field
),
) {
val (icon, description) = remember(visible) {
if (visible) Icons.Outlined.VisibilityOff to R.string.hide_password_field else Icons.Outlined.Visibility to R.string.show_password_field
}
Icon(icon, stringResource(description))
}
},
keyboardOptions = KeyboardOptions(

View File

@@ -5,7 +5,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarColors
@@ -19,6 +18,7 @@ import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import app.revanced.manager.R
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -48,16 +48,15 @@ fun SearchView(
onExpandedChange = onActiveChange,
placeholder = placeholder,
leadingIcon = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.back),
onClick = { onActiveChange(false) }
) {
IconButton(onClick = { onActiveChange(false) }) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
stringResource(R.string.back)
)
}
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
stringResource(R.string.back)
)
}
}
)

View File

@@ -22,7 +22,7 @@ import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefaul
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
import app.revanced.manager.ui.component.ExceptionViewerDialog
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import kotlinx.coroutines.launch
import org.koin.compose.koinInject
@@ -74,29 +74,27 @@ fun BundleInformationDialog(
},
actions = {
if (!bundle.isDefault) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onDeleteRequest,
tooltip = stringResource(R.string.delete),
) {
IconButton(onClick = onDeleteRequest) {
Icon(
Icons.Outlined.DeleteOutline,
stringResource(R.string.delete)
)
}
Icon(
Icons.Outlined.DeleteOutline,
stringResource(R.string.delete)
)
}
}
if (!isLocal && hasNetwork) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onUpdate,
tooltip = stringResource(R.string.refresh),
) {
IconButton(onClick = onUpdate) {
Icon(
Icons.Outlined.Update,
stringResource(R.string.refresh)
)
}
Icon(
Icons.Outlined.Update,
stringResource(R.string.refresh)
)
}
}
}

View File

@@ -2,7 +2,6 @@ package app.revanced.manager.ui.component.bundle
import androidx.compose.foundation.layout.RowScope
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
@@ -14,7 +13,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import app.revanced.manager.R
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -37,13 +36,12 @@ fun BundleTopBar(
scrollBehavior = scrollBehavior,
navigationIcon = {
if (onBackClick != null) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.back),
onClick = onBackClick
) {
IconButton(onClick = onBackClick) {
backIcon()
}
backIcon()
}
}
},

View File

@@ -0,0 +1,38 @@
package app.revanced.manager.ui.component.haptics
import android.view.HapticFeedbackConstants
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.FloatingActionButtonElevation
import androidx.compose.material3.SmallFloatingActionButton
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import app.revanced.manager.util.withHapticFeedback
@Composable
fun HapticSmallFloatingActionButton (
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = FloatingActionButtonDefaults.smallShape,
containerColor: Color = FloatingActionButtonDefaults.containerColor,
contentColor: Color = contentColorFor(containerColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit,
) {
SmallFloatingActionButton(
onClick = onClick.withHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY),
modifier = modifier,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
elevation = elevation,
interactionSource = interactionSource,
content = content
)
}

View File

@@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
@@ -65,10 +64,10 @@ import app.revanced.manager.ui.component.FloatInputDialog
import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.IntInputDialog
import app.revanced.manager.ui.component.LongInputDialog
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
import app.revanced.manager.ui.component.haptics.HapticRadioButton
import app.revanced.manager.ui.component.haptics.HapticSwitch
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.util.isScrollingUp
import app.revanced.manager.util.mutableStateSetOf
import app.revanced.manager.util.saver.snapshotStateListSaver
@@ -112,13 +111,12 @@ private interface OptionEditor<T : Any> {
@Composable
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.edit),
onClick = { clickAction(scope) }
) {
IconButton(onClick = { clickAction(scope) }) {
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
}
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
}
}
@@ -253,18 +251,12 @@ private object StringOptionEditor : OptionEditor<String> {
},
trailingIcon = {
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.string_option_menu_description),
onClick = { showDropdownMenu = true }
) {
IconButton(
onClick = { showDropdownMenu = true }
) {
Icon(
Icons.Outlined.MoreVert,
stringResource(R.string.string_option_menu_description)
)
}
Icon(Icons.Outlined.MoreVert, stringResource(R.string.string_option_menu_description))
}
DropdownMenu(
@@ -560,47 +552,43 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
},
actions = {
if (deleteMode) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.select_deselect_all),
) {
IconButton(
onClick = {
if (items.size == deletionTargets.size) deletionTargets.clear()
else deletionTargets.addAll(items.map { it.key })
}
) {
Icon(
Icons.Outlined.SelectAll,
stringResource(R.string.select_deselect_all)
)
onClick = {
if (items.size == deletionTargets.size) deletionTargets.clear()
else deletionTargets.addAll(items.map { it.key })
}
) {
Icon(
Icons.Outlined.SelectAll,
stringResource(R.string.select_deselect_all)
)
}
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.delete),
) {
IconButton(
onClick = {
items.removeIf { it.key in deletionTargets }
deletionTargets.clear()
deleteMode = false
}
) {
Icon(
Icons.Outlined.Delete,
stringResource(R.string.delete)
)
onClick = {
items.removeIf { it.key in deletionTargets }
deletionTargets.clear()
deleteMode = false
}
) {
Icon(
Icons.Outlined.Delete,
stringResource(R.string.delete)
)
}
} else {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.reset),
onClick = items::clear
) {
IconButton(onClick = items::clear) {
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
}
Icon(
Icons.Outlined.Restore,
stringResource(R.string.reset)
)
}
}
}
@@ -667,19 +655,15 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
),
tonalElevation = if (deleteMode && item.key in deletionTargets) 8.dp else 0.dp,
leadingContent = {
TooltipWrap(
modifier = Modifier,
tooltip = stringResource(R.string.drag_handle),
TooltipIconButton(
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
tooltip = stringResource(R.string.delete),
onClick = { }
) {
IconButton(
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
onClick = {},
) {
Icon(
Icons.Filled.DragHandle,
stringResource(R.string.drag_handle)
)
}
Icon(
Icons.Filled.DragHandle,
stringResource(R.string.drag_handle)
)
}
},
headlineContent = {

View File

@@ -5,7 +5,6 @@ import androidx.compose.foundation.clickable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Edit
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -17,7 +16,7 @@ import androidx.compose.ui.res.stringResource
import app.revanced.manager.R
import app.revanced.manager.domain.manager.base.Preference
import app.revanced.manager.ui.component.IntInputDialog
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@@ -66,16 +65,15 @@ fun IntegerItem(
headlineContent = stringResource(headline),
supportingContent = stringResource(description),
trailingContent = {
TooltipWrap(
modifier = Modifier,
TooltipIconButton(
modifier = modifier,
onClick = { dialogOpen = true },
tooltip = stringResource(R.string.edit),
) {
IconButton(onClick = { dialogOpen = true }) {
Icon(
Icons.Outlined.Edit,
contentDescription = stringResource(R.string.edit)
)
}
Icon(
imageVector = Icons.Outlined.Edit,
contentDescription = stringResource(R.string.edit),
)
}
}
)

View File

@@ -0,0 +1,115 @@
package app.revanced.manager.ui.component.tooltip
import android.annotation.SuppressLint
import androidx.annotation.Discouraged
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.FloatingActionButtonElevation
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.window.PopupPositionProvider
import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton
/**
* [HapticFloatingActionButton] with tooltip-specific params.
*
* @param tooltip [String] text to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [HapticFloatingActionButton]
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipFloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = FloatingActionButtonDefaults.shape,
containerColor: Color = FloatingActionButtonDefaults.containerColor,
contentColor: Color = contentColorFor(containerColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
tooltip: String,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit)
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
HapticFloatingActionButton(
onClick = onClick,
modifier = modifier,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
elevation = elevation,
interactionSource = interactionSource,
content = content,
)
}
}
/**
* [HapticFloatingActionButton] with tooltip-specific params.
*
* @param tooltip [Int] or `id` string resource to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [HapticFloatingActionButton]
*/
@SuppressLint("DiscouragedApi")
@Discouraged(
message = "Consider using string resource for tooltip text in production to make "
+ "the text translatable."
)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipFloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = FloatingActionButtonDefaults.shape,
containerColor: Color = FloatingActionButtonDefaults.containerColor,
contentColor: Color = contentColorFor(containerColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
@StringRes tooltip: Int,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit)
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
HapticFloatingActionButton(
onClick = onClick,
modifier = modifier,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
elevation = elevation,
interactionSource = interactionSource,
content = content,
)
}
}

View File

@@ -0,0 +1,100 @@
package app.revanced.manager.ui.component.tooltip
import android.annotation.SuppressLint
import androidx.annotation.Discouraged
import androidx.annotation.StringRes
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonColors
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.TooltipDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.window.PopupPositionProvider
/**
* [IconButton] with tooltip-specific params.
*
* @param tooltip [String] text to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [IconButton]
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipIconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
tooltip: String,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit),
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
IconButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = colors,
interactionSource = interactionSource,
content = content,
)
}
}
/**
* [IconButton] with tooltip-specific params.
*
* @param tooltip [Int] or `id` string resource to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [IconButton]
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipIconButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
colors: IconButtonColors = IconButtonDefaults.iconButtonColors(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
@StringRes tooltip: Int,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit),
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
IconButton(
onClick = onClick,
modifier = modifier,
enabled = enabled,
colors = colors,
interactionSource = interactionSource,
content = content,
)
}
}

View File

@@ -0,0 +1,111 @@
package app.revanced.manager.ui.component.tooltip
import android.annotation.SuppressLint
import androidx.annotation.Discouraged
import androidx.annotation.StringRes
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FloatingActionButtonDefaults
import androidx.compose.material3.FloatingActionButtonElevation
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.contentColorFor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.window.PopupPositionProvider
import app.revanced.manager.ui.component.haptics.HapticSmallFloatingActionButton
/**
* [HapticSmallFloatingActionButton] with tooltip-specific params.
*
* @param tooltip [String] text to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [HapticSmallFloatingActionButton]
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipSmallFloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = FloatingActionButtonDefaults.smallShape,
containerColor: Color = FloatingActionButtonDefaults.containerColor,
contentColor: Color = contentColorFor(containerColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
tooltip: String,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit)
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
HapticSmallFloatingActionButton(
onClick = onClick,
modifier = modifier,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
elevation = elevation,
interactionSource = interactionSource,
content = content,
)
}
}
/**
* [HapticSmallFloatingActionButton] with tooltip-specific params.
*
* @param tooltip [Int] or `id` string resource to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [HapticSmallFloatingActionButton]
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TooltipSmallFloatingActionButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
shape: Shape = FloatingActionButtonDefaults.smallShape,
containerColor: Color = FloatingActionButtonDefaults.containerColor,
contentColor: Color = contentColorFor(containerColor),
elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
@StringRes tooltip: Int,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable (() -> Unit)
) {
TooltipWrap(
modifier = modifier,
tooltip = tooltip,
positionProvider = positionProvider,
haptic = haptic,
hapticFeedbackType = hapticFeedbackType,
) {
HapticSmallFloatingActionButton(
onClick = onClick,
modifier = modifier,
shape = shape,
containerColor = containerColor,
contentColor = contentColor,
elevation = elevation,
interactionSource = interactionSource,
content = content,
)
}
}

View File

@@ -1,4 +1,4 @@
package app.revanced.manager.ui.component
package app.revanced.manager.ui.component.tooltip
import androidx.annotation.StringRes
import androidx.compose.material3.ExperimentalMaterial3Api
@@ -18,10 +18,12 @@ import androidx.compose.ui.window.PopupPositionProvider
/**
* Wraps a composable with a tooltip.
*
* @param modifier the [Modifier] to be applied to the [TooltipBox]
* @param tooltip the text to be displayed in the [TooltipBox]
* @param positionProvider Anchor point for the tooltip, defaults to [TooltipDefaults.rememberPlainTooltipPositionProvider]
* @param content The composable UI to be wrapped with [TooltipBox]
* @param modifier the [Modifier] to applied to Tooltip.
* @param tooltip [String] text to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param content The composable UI to wrapped with.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [TooltipBox]
*/
@@ -31,36 +33,37 @@ fun TooltipWrap(
modifier: Modifier,
tooltip: String,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable () -> Unit
) {
val tooltipState = rememberTooltipState()
val haptic = LocalHapticFeedback.current
val localHaptic = LocalHapticFeedback.current
LaunchedEffect(tooltipState.isVisible) {
if (tooltipState.isVisible) {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
if (tooltipState.isVisible && haptic) {
localHaptic.performHapticFeedback(hapticFeedbackType)
}
}
TooltipBox(
modifier = modifier,
positionProvider = positionProvider,
tooltip = {
PlainTooltip { Text(tooltip) }
},
state = tooltipState
) {
content()
}
tooltip = { PlainTooltip { Text(tooltip) } },
state = tooltipState,
content = content,
)
}
/**
* Wraps a composable with a tooltip.
*
* @param modifier the [Modifier] to be applied to the [TooltipBox]
* @param tooltip the R.string to be displayed in the [TooltipBox]
* @param positionProvider Anchor point for the tooltip, defaults to [TooltipDefaults.rememberPlainTooltipPositionProvider]
* @param content The composable UI to be wrapped with [TooltipBox]
* @param modifier the [Modifier] to applied to tooltip.
* @param tooltip [Int] or `id` string resource to show in a tooltip.
* @param positionProvider [PopupPositionProvider] Anchor point for the tooltip.
* @param content The composable UI to wrapped with.
* @param haptic Whether to perform haptic feedback when the tooltip shown.
* @param hapticFeedbackType The type of haptic feedback to perform.
*
* @see [TooltipBox]
*/
@@ -70,25 +73,24 @@ fun TooltipWrap(
modifier: Modifier,
@StringRes tooltip: Int,
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
haptic: Boolean = true,
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
content: @Composable () -> Unit
) {
val tooltipState = rememberTooltipState()
val haptic = LocalHapticFeedback.current
val localHaptic = LocalHapticFeedback.current
LaunchedEffect(tooltipState.isVisible) {
if (tooltipState.isVisible) {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
if (tooltipState.isVisible && haptic) {
localHaptic.performHapticFeedback(hapticFeedbackType)
}
}
TooltipBox(
modifier = modifier,
positionProvider = positionProvider,
tooltip = {
PlainTooltip { Text(stringResource(tooltip)) }
},
state = tooltipState
) {
content()
}
tooltip = { PlainTooltip { Text(stringResource(tooltip)) } },
state = tooltipState,
content = content,
)
}

View File

@@ -16,7 +16,6 @@ import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
@@ -44,7 +43,7 @@ import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.LoadingIndicator
import app.revanced.manager.ui.component.NonSuggestedVersionDialog
import app.revanced.manager.ui.component.SearchView
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.model.SelectedApp
import app.revanced.manager.ui.viewmodel.AppSelectorViewModel
import app.revanced.manager.util.APK_MIMETYPE
@@ -163,13 +162,15 @@ fun AppSelectorScreen(
scrollBehavior = scrollBehavior,
onBackClick = onBackClick,
actions = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.search_patches),
onClick = { search = true }
) {
IconButton(onClick = { search = true }) {
Icon(Icons.Outlined.Search, stringResource(R.string.search))
}
Icon(
Icons.Outlined.Search,
stringResource(R.string.search)
)
}
}
)

View File

@@ -64,11 +64,11 @@ import app.revanced.manager.ui.component.AutoUpdatesDialog
import app.revanced.manager.ui.component.AvailableUpdateDialog
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.NotificationCard
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.bundle.BundleTopBar
import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
import app.revanced.manager.ui.component.haptics.HapticFloatingActionButton
import app.revanced.manager.ui.component.haptics.HapticTab
import app.revanced.manager.ui.component.tooltip.TooltipFloatingActionButton
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.viewmodel.DashboardViewModel
import app.revanced.manager.util.RequestInstallAppsContract
import app.revanced.manager.util.toast
@@ -184,36 +184,30 @@ fun DashboardScreen(
)
},
actions = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = {
showDeleteConfirmationDialog = true
},
tooltip = stringResource(R.string.delete),
) {
IconButton(
onClick = {
showDeleteConfirmationDialog = true
}
) {
Icon(
Icons.Outlined.DeleteOutline,
stringResource(R.string.delete)
)
}
Icon(
Icons.Outlined.DeleteOutline,
stringResource(R.string.delete)
)
}
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = {
vm.selectedSources.forEach { vm.update(it) }
vm.cancelSourceSelection()
},
tooltip = stringResource(R.string.refresh),
) {
IconButton(
onClick = {
vm.selectedSources.forEach { vm.update(it) }
vm.cancelSourceSelection()
}
) {
Icon(
Icons.Outlined.Refresh,
stringResource(R.string.refresh)
)
}
Icon(
Icons.Outlined.Refresh,
stringResource(R.string.refresh)
)
}
}
)
@@ -222,28 +216,30 @@ fun DashboardScreen(
title = stringResource(R.string.app_name),
actions = {
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onUpdateClick,
tooltip = stringResource(R.string.update),
) {
IconButton(
onClick = onUpdateClick,
) {
BadgedBox(
badge = {
Badge(modifier = Modifier.size(6.dp))
}
) {
Icon(Icons.Outlined.Update, stringResource(R.string.update))
BadgedBox(
badge = {
Badge(modifier = Modifier.size(6.dp))
}
) {
Icon(Icons.Outlined.Update, stringResource(R.string.update))
}
}
}
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = onSettingsClick,
tooltip = stringResource(R.string.settings),
) {
IconButton(onClick = onSettingsClick) {
BadgedBox(
badge = {
Badge(modifier = Modifier.size(6.dp))
}
) {
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
}
}
@@ -253,40 +249,37 @@ fun DashboardScreen(
}
},
floatingActionButton = {
TooltipWrap(
TooltipFloatingActionButton(
modifier = Modifier,
tooltip = stringResource(R.string.add),
) {
HapticFloatingActionButton(
onClick = {
vm.cancelSourceSelection()
onClick = {
vm.cancelSourceSelection()
when (pagerState.currentPage) {
DashboardPage.DASHBOARD.ordinal -> {
if (availablePatches < 1) {
androidContext.toast(androidContext.getString(R.string.patches_unavailable))
composableScope.launch {
pagerState.animateScrollToPage(
DashboardPage.BUNDLES.ordinal
)
}
return@HapticFloatingActionButton
when (pagerState.currentPage) {
DashboardPage.DASHBOARD.ordinal -> {
if (availablePatches < 1) {
androidContext.toast(androidContext.getString(R.string.patches_unavailable))
composableScope.launch {
pagerState.animateScrollToPage(
DashboardPage.BUNDLES.ordinal
)
}
if (vm.android11BugActive) {
showAndroid11Dialog = true
return@HapticFloatingActionButton
}
onAppSelectorClick()
return@TooltipFloatingActionButton
}
if (vm.android11BugActive) {
showAndroid11Dialog = true
return@TooltipFloatingActionButton
}
DashboardPage.BUNDLES.ordinal -> {
showAddBundleDialog = true
}
onAppSelectorClick()
}
DashboardPage.BUNDLES.ordinal -> {
showAddBundleDialog = true
}
}
) { Icon(Icons.Default.Add, stringResource(R.string.add)) }
}
}
) { Icon(Icons.Default.Add, stringResource(R.string.add)) }
}
) { paddingValues ->
Column(Modifier.padding(paddingValues)) {

View File

@@ -25,7 +25,6 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
@@ -48,10 +47,10 @@ import app.revanced.manager.ui.component.AppScaffold
import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.InstallerStatusDialog
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
import app.revanced.manager.ui.component.patcher.InstallPickerDialog
import app.revanced.manager.ui.component.patcher.Steps
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.model.StepCategory
import app.revanced.manager.ui.viewmodel.PatcherViewModel
import app.revanced.manager.util.APK_MIMETYPE
@@ -165,27 +164,21 @@ fun PatcherScreen(
bottomBar = {
BottomAppBar(
actions = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = { exportApkLauncher.launch("${viewModel.packageName}_${viewModel.version}_revanced_patched.apk") },
enabled = patcherSucceeded == true,
tooltip = stringResource(R.string.save_apk),
) {
IconButton(
onClick = { exportApkLauncher.launch("${viewModel.packageName}_${viewModel.version}_revanced_patched.apk") },
enabled = patcherSucceeded == true
) {
Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk))
}
Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk))
}
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = { viewModel.exportLogs(context) },
enabled = patcherSucceeded != null,
tooltip = stringResource(R.string.save_logs),
) {
IconButton(
onClick = { viewModel.exportLogs(context) },
enabled = patcherSucceeded != null
) {
Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs))
}
Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs))
}
},
floatingActionButton = {

View File

@@ -41,7 +41,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ScrollableTabRow
import androidx.compose.material3.SmallFloatingActionButton
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.surfaceColorAtElevation
@@ -69,11 +68,12 @@ import app.revanced.manager.ui.component.FullscreenDialog
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.SafeguardDialog
import app.revanced.manager.ui.component.SearchBar
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.haptics.HapticCheckbox
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
import app.revanced.manager.ui.component.haptics.HapticTab
import app.revanced.manager.ui.component.patches.OptionItem
import app.revanced.manager.ui.component.tooltip.TooltipFloatingActionButton
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_INCOMPATIBLE
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
@@ -260,25 +260,22 @@ fun PatchesSelectorScreen(
animationSpec = tween(durationMillis = 400, easing = EaseInOut),
label = "SearchBar back button"
)
TooltipWrap(
modifier = Modifier,
TooltipIconButton(
modifier = Modifier.rotate(rotation),
onClick = {
if (searchExpanded) {
setSearchExpanded(false)
} else {
onBackClick()
}
},
tooltip = stringResource(R.string.back),
) {
IconButton(
onClick = {
if (searchExpanded) {
setSearchExpanded(false)
} else {
onBackClick()
}
}
) {
Icon(
modifier = Modifier.rotate(rotation),
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back)
)
}
Icon(
modifier = Modifier.rotate(rotation),
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = stringResource(R.string.back)
)
}
},
trailingIcon = {
@@ -288,31 +285,27 @@ fun PatchesSelectorScreen(
transitionSpec = { fadeIn() togetherWith fadeOut() }
) { searchExpanded ->
if (searchExpanded) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = { setQuery("") },
enabled = query.isNotEmpty(),
tooltip = stringResource(R.string.clear),
) {
IconButton(
onClick = { setQuery("") },
enabled = query.isNotEmpty()
) {
Icon(
imageVector = Icons.Filled.Close,
contentDescription = stringResource(R.string.clear)
)
}
Icon(
imageVector = Icons.Filled.Close,
contentDescription = stringResource(R.string.clear)
)
}
} else {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = { showBottomSheet = true },
tooltip = stringResource(R.string.more),
) {
IconButton(onClick = { showBottomSheet = true }) {
Icon(
imageVector = Icons.Outlined.FilterList,
contentDescription = stringResource(R.string.more)
)
}
Icon(
imageVector = Icons.Outlined.FilterList,
contentDescription = stringResource(R.string.more)
)
}
}
}
@@ -370,16 +363,23 @@ fun PatchesSelectorScreen(
horizontalAlignment = Alignment.End,
verticalArrangement = Arrangement.spacedBy(4.dp)
) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
onClick = { showBottomSheet = true },
tooltip = stringResource(R.string.more),
) {
Icon(
imageVector = Icons.Outlined.FilterList,
contentDescription = stringResource(R.string.more)
)
}
TooltipFloatingActionButton(
modifier = Modifier,
tooltip = stringResource(R.string.reset),
onClick = viewModel::reset,
containerColor = MaterialTheme.colorScheme.tertiaryContainer
) {
SmallFloatingActionButton(
onClick = viewModel::reset,
containerColor = MaterialTheme.colorScheme.tertiaryContainer
) {
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
}
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
}
HapticExtendedFloatingActionButton(
text = {
@@ -562,16 +562,15 @@ fun ListHeader(
},
trailingContent = onHelpClick?.let {
{
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.help),
onClick = it
) {
IconButton(onClick = it) {
Icon(
Icons.AutoMirrored.Outlined.HelpOutline,
stringResource(R.string.help)
)
}
Icon(
Icons.AutoMirrored.Outlined.HelpOutline,
stringResource(R.string.help)
)
}
}
},
@@ -646,13 +645,12 @@ private fun OptionsDialog(
title = patch.name,
onBackClick = onDismissRequest,
actions = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.reset),
onClick = reset
) {
IconButton(onClick = reset) {
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
}
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
}
}
)

View File

@@ -19,7 +19,6 @@ import androidx.compose.material.icons.outlined.MailOutline
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FilledTonalButton
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
@@ -49,8 +48,8 @@ import app.revanced.manager.R
import app.revanced.manager.network.dto.ReVancedSocial
import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.model.navigation.Settings
import app.revanced.manager.ui.viewmodel.AboutViewModel
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.DEVELOPER_OPTIONS_TAPS
@@ -253,21 +252,17 @@ fun AboutSettingsScreen(
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
) {
socialButtons.forEach { (icon, text, onClick) ->
TooltipWrap(
modifier = Modifier,
TooltipIconButton(
modifier = Modifier.padding(end = 8.dp),
tooltip = text,
onClick = onClick
) {
IconButton(
onClick = onClick,
modifier = Modifier.padding(end = 8.dp),
) {
Icon(
icon,
contentDescription = text,
modifier = Modifier.size(28.dp),
tint = MaterialTheme.colorScheme.secondary
)
}
Icon(
icon,
contentDescription = text,
modifier = Modifier.size(28.dp),
tint = MaterialTheme.colorScheme.secondary
)
}
}
}

View File

@@ -21,7 +21,6 @@ import androidx.compose.material.icons.outlined.Restore
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
@@ -48,11 +47,11 @@ import app.revanced.manager.R
import app.revanced.manager.ui.component.AppTopBar
import app.revanced.manager.ui.component.ColumnWithScrollbar
import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.settings.BooleanItem
import app.revanced.manager.ui.component.settings.IntegerItem
import app.revanced.manager.ui.component.settings.SafeguardBooleanItem
import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.viewmodel.AdvancedSettingsViewModel
import app.revanced.manager.util.toast
import app.revanced.manager.util.withHapticFeedback
@@ -244,13 +243,12 @@ private fun APIUrlDialog(currentUrl: String, defaultUrl: String, onSubmit: (Stri
onValueChange = { url = it },
label = { Text(stringResource(R.string.api_url)) },
trailingIcon = {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.api_url_dialog_reset),
onClick = { url = defaultUrl }
) {
IconButton(onClick = { url = defaultUrl }) {
Icon(Icons.Outlined.Restore, stringResource(R.string.api_url_dialog_reset))
}
Icon(Icons.Outlined.Restore, stringResource(R.string.api_url_dialog_reset))
}
}
)

View File

@@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Search
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@@ -45,9 +46,10 @@ import app.revanced.manager.ui.component.ExceptionViewerDialog
import app.revanced.manager.ui.component.GroupHeader
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
import app.revanced.manager.ui.component.ConfirmDialog
import app.revanced.manager.ui.component.TooltipWrap
import app.revanced.manager.ui.component.tooltip.TooltipWrap
import app.revanced.manager.ui.component.haptics.HapticCheckbox
import app.revanced.manager.ui.component.settings.SettingsListItem
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
import org.koin.androidx.compose.koinViewModel
import java.security.MessageDigest
@@ -82,13 +84,12 @@ fun DownloadsSettingsScreen(
onBackClick = onBackClick,
actions = {
if (viewModel.appSelection.isNotEmpty()) {
TooltipWrap(
TooltipIconButton(
modifier = Modifier,
tooltip = stringResource(R.string.delete),
onClick = { showDeleteConfirmationDialog = true }
) {
IconButton(onClick = { showDeleteConfirmationDialog = true }) {
Icon(Icons.Default.Delete, stringResource(R.string.delete))
}
Icon(Icons.Default.Delete, stringResource(R.string.delete))
}
}
}