From 438fa485bd309ffb19e39a2025c5b968fb23db61 Mon Sep 17 00:00:00 2001 From: Pun Butrach Date: Fri, 11 Jul 2025 16:04:05 +0700 Subject: [PATCH] feat: Tooltip{component}.kt --- .../manager/ui/component/AppScaffold.kt | 16 ++- .../manager/ui/component/ArrowButton.kt | 21 ++-- .../ui/component/ExceptionViewerDialog.kt | 49 ++++---- .../manager/ui/component/NotificationCard.kt | 17 ++- .../manager/ui/component/PasswordField.kt | 23 ++-- .../manager/ui/component/SearchView.kt | 15 ++- .../bundle/BundleInformationDialog.kt | 28 ++--- .../ui/component/bundle/BundleTopBar.kt | 10 +- .../HapticSmallFloatingActionButton.kt | 38 ++++++ .../ui/component/patches/OptionFields.kt | 96 ++++++-------- .../ui/component/settings/IntegerItem.kt | 18 ++- .../tooltip/TooltipFloatingActionButton.kt | 115 +++++++++++++++++ .../ui/component/tooltip/TooltipIconButton.kt | 100 +++++++++++++++ .../TooltipSmallFloatingActionButton.kt | 111 ++++++++++++++++ .../ui/component/{ => tooltip}/TooltipWrap.kt | 60 ++++----- .../manager/ui/screen/AppSelectorScreen.kt | 13 +- .../manager/ui/screen/DashboardScreen.kt | 119 +++++++++--------- .../manager/ui/screen/PatcherScreen.kt | 25 ++-- .../ui/screen/PatchesSelectorScreen.kt | 106 ++++++++-------- .../ui/screen/settings/AboutSettingsScreen.kt | 25 ++-- .../screen/settings/AdvancedSettingsScreen.kt | 10 +- .../settings/DownloadsSettingsScreen.kt | 11 +- 22 files changed, 671 insertions(+), 355 deletions(-) create mode 100644 app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSmallFloatingActionButton.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipFloatingActionButton.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipIconButton.kt create mode 100644 app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipSmallFloatingActionButton.kt rename app/src/main/java/app/revanced/manager/ui/component/{ => tooltip}/TooltipWrap.kt (51%) diff --git a/app/src/main/java/app/revanced/manager/ui/component/AppScaffold.kt b/app/src/main/java/app/revanced/manager/ui/component/AppScaffold.kt index 3b03cc07..a29cd846 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/AppScaffold.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/AppScaffold.kt @@ -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() } } }, diff --git a/app/src/main/java/app/revanced/manager/ui/component/ArrowButton.kt b/app/src/main/java/app/revanced/manager/ui/component/ArrowButton.kt index 3a2c385a..63dcffea 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/ArrowButton.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/ArrowButton.kt @@ -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, diff --git a/app/src/main/java/app/revanced/manager/ui/component/ExceptionViewerDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/ExceptionViewerDialog.kt index 9f26e4dc..1af26706 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/ExceptionViewerDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/ExceptionViewerDialog.kt @@ -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) + ) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/NotificationCard.kt b/app/src/main/java/app/revanced/manager/ui/component/NotificationCard.kt index 2a24eeef..b2976dca 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/NotificationCard.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/NotificationCard.kt @@ -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, + ) } } } diff --git a/app/src/main/java/app/revanced/manager/ui/component/PasswordField.kt b/app/src/main/java/app/revanced/manager/ui/component/PasswordField.kt index 53250434..1ad0caa6 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/PasswordField.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/PasswordField.kt @@ -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( diff --git a/app/src/main/java/app/revanced/manager/ui/component/SearchView.kt b/app/src/main/java/app/revanced/manager/ui/component/SearchView.kt index aa78d209..fd76c6a7 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/SearchView.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/SearchView.kt @@ -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) + ) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleInformationDialog.kt b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleInformationDialog.kt index 8a6768f6..555b4604 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleInformationDialog.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleInformationDialog.kt @@ -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) + ) } } } diff --git a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleTopBar.kt b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleTopBar.kt index af9fe1c4..da4fa2d1 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleTopBar.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/bundle/BundleTopBar.kt @@ -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() } } }, diff --git a/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSmallFloatingActionButton.kt b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSmallFloatingActionButton.kt new file mode 100644 index 00000000..36b97511 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/haptics/HapticSmallFloatingActionButton.kt @@ -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 + ) +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt b/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt index 4bc0ca79..4322fb34 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/patches/OptionFields.kt @@ -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 { @Composable fun ListItemTrailingContent(scope: OptionEditorScope) { - 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 { }, 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(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(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 = { diff --git a/app/src/main/java/app/revanced/manager/ui/component/settings/IntegerItem.kt b/app/src/main/java/app/revanced/manager/ui/component/settings/IntegerItem.kt index 83fd2985..cdd967b8 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/settings/IntegerItem.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/settings/IntegerItem.kt @@ -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), + ) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipFloatingActionButton.kt b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipFloatingActionButton.kt new file mode 100644 index 00000000..bbf3b257 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipFloatingActionButton.kt @@ -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, + ) + } +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipIconButton.kt b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipIconButton.kt new file mode 100644 index 00000000..fa4bd117 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipIconButton.kt @@ -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, + ) + } +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipSmallFloatingActionButton.kt b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipSmallFloatingActionButton.kt new file mode 100644 index 00000000..8f883305 --- /dev/null +++ b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipSmallFloatingActionButton.kt @@ -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, + ) + } +} diff --git a/app/src/main/java/app/revanced/manager/ui/component/TooltipWrap.kt b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipWrap.kt similarity index 51% rename from app/src/main/java/app/revanced/manager/ui/component/TooltipWrap.kt rename to app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipWrap.kt index bcbbf0a7..53a85fa2 100644 --- a/app/src/main/java/app/revanced/manager/ui/component/TooltipWrap.kt +++ b/app/src/main/java/app/revanced/manager/ui/component/tooltip/TooltipWrap.kt @@ -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, + ) } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt index 79ce80a9..9c28870d 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/AppSelectorScreen.kt @@ -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) + ) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt index cdce7d4a..25ba404d 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/DashboardScreen.kt @@ -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)) { diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt index 27faeddf..52067dbc 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatcherScreen.kt @@ -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 = { diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt index c7f07264..95acd313 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatchesSelectorScreen.kt @@ -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)) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt index 98f0ccbe..e096ae2e 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AboutSettingsScreen.kt @@ -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 + ) } } } diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt index 742ecedc..e70faa87 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/AdvancedSettingsScreen.kt @@ -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)) } } ) diff --git a/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt index ba1943fc..bbf31a4a 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/settings/DownloadsSettingsScreen.kt @@ -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)) } } }