mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2025-07-12 07:14:23 +08:00
Compare commits
6 Commits
compose-de
...
feat/toolt
Author | SHA1 | Date | |
---|---|---|---|
05afc6bd0c | |||
a2caffb089 | |||
71b0fd48ab | |||
438fa485bd | |||
1510aa58f2 | |||
111c74329f |
@ -6,7 +6,6 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
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.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -69,7 +69,11 @@ fun AppTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
IconButton(onClick = onBackClick) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = onBackClick,
|
||||||
|
tooltip = stringResource(R.string.back),
|
||||||
|
) {
|
||||||
backIcon()
|
backIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +112,11 @@ fun AppTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
IconButton(onClick = onBackClick) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = onBackClick,
|
||||||
|
tooltip = stringResource(R.string.back),
|
||||||
|
) {
|
||||||
backIcon()
|
backIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import androidx.compose.animation.core.animateFloatAsState
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ArrowButton(
|
fun ArrowButton(
|
||||||
@ -27,7 +27,11 @@ fun ArrowButton(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onClick?.let {
|
onClick?.let {
|
||||||
IconButton(onClick = it) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = it,
|
||||||
|
tooltip = stringResource(description),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.KeyboardArrowUp,
|
imageVector = Icons.Filled.KeyboardArrowUp,
|
||||||
contentDescription = stringResource(description),
|
contentDescription = stringResource(description),
|
||||||
|
@ -9,7 +9,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|||||||
import androidx.compose.material.icons.outlined.Share
|
import androidx.compose.material.icons.outlined.Share
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@ -18,6 +17,7 @@ import androidx.compose.ui.platform.LocalContext
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -39,7 +39,8 @@ fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
val sendIntent: Intent = Intent().apply {
|
val sendIntent: Intent = Intent().apply {
|
||||||
action = Intent.ACTION_SEND
|
action = Intent.ACTION_SEND
|
||||||
@ -52,7 +53,8 @@ fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
|
|||||||
|
|
||||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||||
context.startActivity(shareIntent)
|
context.startActivity(shareIntent)
|
||||||
}
|
},
|
||||||
|
tooltip = stringResource(R.string.share),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.Share,
|
Icons.Outlined.Share,
|
||||||
|
@ -14,7 +14,6 @@ import androidx.compose.material.icons.outlined.Close
|
|||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NotificationCard(
|
fun NotificationCard(
|
||||||
@ -138,7 +138,11 @@ fun NotificationCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (onDismiss != null) {
|
if (onDismiss != null) {
|
||||||
IconButton(onClick = onDismiss) {
|
TooltipIconButton(
|
||||||
|
modifier = modifier,
|
||||||
|
onClick = onDismiss,
|
||||||
|
tooltip = stringResource(R.string.close),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.Close,
|
imageVector = Icons.Outlined.Close,
|
||||||
contentDescription = stringResource(R.string.close),
|
contentDescription = stringResource(R.string.close),
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.outlined.Visibility
|
import androidx.compose.material.icons.outlined.Visibility
|
||||||
import androidx.compose.material.icons.outlined.VisibilityOff
|
import androidx.compose.material.icons.outlined.VisibilityOff
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
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.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (String) -> Unit, label: @Composable (() -> Unit)? = null, placeholder: @Composable (() -> Unit)? = null) {
|
fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (String) -> Unit, label: @Composable (() -> Unit)? = null, placeholder: @Composable (() -> Unit)? = null) {
|
||||||
@ -33,9 +33,15 @@ fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (
|
|||||||
label = label,
|
label = label,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
IconButton(onClick = {
|
TooltipIconButton(
|
||||||
visible = !visible
|
modifier = Modifier,
|
||||||
}) {
|
onClick = {
|
||||||
|
visible = !visible
|
||||||
|
},
|
||||||
|
tooltip = if (visible) stringResource(R.string.show_password_field) else stringResource(
|
||||||
|
R.string.hide_password_field
|
||||||
|
),
|
||||||
|
) {
|
||||||
val (icon, description) = remember(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
|
if (visible) Icons.Outlined.VisibilityOff to R.string.hide_password_field else Icons.Outlined.Visibility to R.string.show_password_field
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.SearchBar
|
import androidx.compose.material3.SearchBar
|
||||||
import androidx.compose.material3.SearchBarColors
|
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.platform.LocalSoftwareKeyboardController
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -48,7 +48,11 @@ fun SearchView(
|
|||||||
onExpandedChange = onActiveChange,
|
onExpandedChange = onActiveChange,
|
||||||
placeholder = placeholder,
|
placeholder = placeholder,
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
IconButton(onClick = { onActiveChange(false) }) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.back),
|
||||||
|
onClick = { onActiveChange(false) }
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.AutoMirrored.Filled.ArrowBack,
|
Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
stringResource(R.string.back)
|
stringResource(R.string.back)
|
||||||
|
@ -22,6 +22,7 @@ import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.isDefaul
|
|||||||
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
|
import app.revanced.manager.domain.bundles.PatchBundleSource.Extensions.nameState
|
||||||
import app.revanced.manager.ui.component.ExceptionViewerDialog
|
import app.revanced.manager.ui.component.ExceptionViewerDialog
|
||||||
import app.revanced.manager.ui.component.FullscreenDialog
|
import app.revanced.manager.ui.component.FullscreenDialog
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.compose.koinInject
|
import org.koin.compose.koinInject
|
||||||
|
|
||||||
@ -73,7 +74,11 @@ fun BundleInformationDialog(
|
|||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (!bundle.isDefault) {
|
if (!bundle.isDefault) {
|
||||||
IconButton(onClick = onDeleteRequest) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = onDeleteRequest,
|
||||||
|
tooltip = stringResource(R.string.delete),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.DeleteOutline,
|
Icons.Outlined.DeleteOutline,
|
||||||
stringResource(R.string.delete)
|
stringResource(R.string.delete)
|
||||||
@ -81,7 +86,11 @@ fun BundleInformationDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isLocal && hasNetwork) {
|
if (!isLocal && hasNetwork) {
|
||||||
IconButton(onClick = onUpdate) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = onUpdate,
|
||||||
|
tooltip = stringResource(R.string.refresh),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.Update,
|
Icons.Outlined.Update,
|
||||||
stringResource(R.string.refresh)
|
stringResource(R.string.refresh)
|
||||||
|
@ -2,7 +2,6 @@ package app.revanced.manager.ui.component.bundle
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
@ -10,7 +9,11 @@ import androidx.compose.material3.TopAppBarDefaults
|
|||||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import app.revanced.manager.R
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
@ -33,7 +36,11 @@ fun BundleTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
IconButton(onClick = onBackClick) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.back),
|
||||||
|
onClick = onBackClick
|
||||||
|
) {
|
||||||
backIcon()
|
backIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,7 @@ fun ImportBundleStep(
|
|||||||
},
|
},
|
||||||
supportingContent = { Text(stringResource(if (patchBundle != null) R.string.file_field_set else R.string.file_field_not_set)) },
|
supportingContent = { Text(stringResource(if (patchBundle != null) R.string.file_field_set else R.string.file_field_not_set)) },
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
|
// TODO: Determine if this button should be [TooltipWrap]'ped
|
||||||
IconButton(onClick = launchPatchActivity) {
|
IconButton(onClick = launchPatchActivity) {
|
||||||
Icon(imageVector = Icons.Default.Topic, contentDescription = null)
|
Icon(imageVector = Icons.Default.Topic, contentDescription = null)
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListItemInfo
|
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
@ -68,19 +67,18 @@ import app.revanced.manager.ui.component.LongInputDialog
|
|||||||
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
||||||
import app.revanced.manager.ui.component.haptics.HapticRadioButton
|
import app.revanced.manager.ui.component.haptics.HapticRadioButton
|
||||||
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
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.isScrollingUp
|
||||||
import app.revanced.manager.util.mutableStateSetOf
|
import app.revanced.manager.util.mutableStateSetOf
|
||||||
import app.revanced.manager.util.saver.snapshotStateListSaver
|
import app.revanced.manager.util.saver.snapshotStateListSaver
|
||||||
import app.revanced.manager.util.saver.snapshotStateSetSaver
|
import app.revanced.manager.util.saver.snapshotStateSetSaver
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
import app.revanced.manager.util.transparentListItemColors
|
import app.revanced.manager.util.transparentListItemColors
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
import org.koin.compose.koinInject
|
import org.koin.compose.koinInject
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
import org.koin.core.component.get
|
import org.koin.core.component.get
|
||||||
import sh.calvin.reorderable.ReorderableItem
|
import sh.calvin.reorderable.ReorderableItem
|
||||||
import sh.calvin.reorderable.rememberReorderableLazyColumnState
|
|
||||||
import sh.calvin.reorderable.rememberReorderableLazyListState
|
import sh.calvin.reorderable.rememberReorderableLazyListState
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -113,7 +111,11 @@ private interface OptionEditor<T : Any> {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
||||||
IconButton(onClick = { clickAction(scope) }) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.edit),
|
||||||
|
onClick = { clickAction(scope) }
|
||||||
|
) {
|
||||||
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,13 +251,12 @@ private object StringOptionEditor : OptionEditor<String> {
|
|||||||
},
|
},
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
|
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.string_option_menu_description),
|
||||||
onClick = { showDropdownMenu = true }
|
onClick = { showDropdownMenu = true }
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(Icons.Outlined.MoreVert, stringResource(R.string.string_option_menu_description))
|
||||||
Icons.Outlined.MoreVert,
|
|
||||||
stringResource(R.string.string_option_menu_description)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
@ -551,7 +552,9 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (deleteMode) {
|
if (deleteMode) {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.select_deselect_all),
|
||||||
onClick = {
|
onClick = {
|
||||||
if (items.size == deletionTargets.size) deletionTargets.clear()
|
if (items.size == deletionTargets.size) deletionTargets.clear()
|
||||||
else deletionTargets.addAll(items.map { it.key })
|
else deletionTargets.addAll(items.map { it.key })
|
||||||
@ -562,7 +565,9 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
stringResource(R.string.select_deselect_all)
|
stringResource(R.string.select_deselect_all)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.delete),
|
||||||
onClick = {
|
onClick = {
|
||||||
items.removeIf { it.key in deletionTargets }
|
items.removeIf { it.key in deletionTargets }
|
||||||
deletionTargets.clear()
|
deletionTargets.clear()
|
||||||
@ -575,8 +580,15 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IconButton(onClick = items::clear) {
|
TooltipIconButton(
|
||||||
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.reset),
|
||||||
|
onClick = items::clear
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.Restore,
|
||||||
|
stringResource(R.string.reset)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -643,9 +655,10 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
),
|
),
|
||||||
tonalElevation = if (deleteMode && item.key in deletionTargets) 8.dp else 0.dp,
|
tonalElevation = if (deleteMode && item.key in deletionTargets) 8.dp else 0.dp,
|
||||||
leadingContent = {
|
leadingContent = {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
|
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
|
||||||
onClick = {},
|
tooltip = stringResource(R.string.delete),
|
||||||
|
onClick = { }
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Filled.DragHandle,
|
Icons.Filled.DragHandle,
|
||||||
|
@ -5,7 +5,6 @@ import androidx.compose.foundation.clickable
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.Edit
|
import androidx.compose.material.icons.outlined.Edit
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -17,6 +16,7 @@ import androidx.compose.ui.res.stringResource
|
|||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.domain.manager.base.Preference
|
import app.revanced.manager.domain.manager.base.Preference
|
||||||
import app.revanced.manager.ui.component.IntInputDialog
|
import app.revanced.manager.ui.component.IntInputDialog
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@ -65,10 +65,14 @@ fun IntegerItem(
|
|||||||
headlineContent = stringResource(headline),
|
headlineContent = stringResource(headline),
|
||||||
supportingContent = stringResource(description),
|
supportingContent = stringResource(description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
IconButton(onClick = { dialogOpen = true }) {
|
TooltipIconButton(
|
||||||
|
modifier = modifier,
|
||||||
|
onClick = { dialogOpen = true },
|
||||||
|
tooltip = stringResource(R.string.edit),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.Edit,
|
imageVector = Icons.Outlined.Edit,
|
||||||
contentDescription = stringResource(R.string.edit)
|
contentDescription = stringResource(R.string.edit),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,109 @@
|
|||||||
|
package app.revanced.manager.ui.component.tooltip
|
||||||
|
|
||||||
|
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.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]
|
||||||
|
*/
|
||||||
|
@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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
package app.revanced.manager.ui.component.tooltip
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package app.revanced.manager.ui.component.tooltip
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
package app.revanced.manager.ui.component.tooltip
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.PlainTooltip
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TooltipBox
|
||||||
|
import androidx.compose.material3.TooltipDefaults
|
||||||
|
import androidx.compose.material3.rememberTooltipState
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.window.PopupPositionProvider
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a composable with a tooltip.
|
||||||
|
*
|
||||||
|
* @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]
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
fun TooltipWrap(
|
||||||
|
modifier: Modifier,
|
||||||
|
tooltip: String,
|
||||||
|
positionProvider: PopupPositionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
|
||||||
|
haptic: Boolean = true,
|
||||||
|
hapticFeedbackType: HapticFeedbackType = HapticFeedbackType.LongPress,
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
val tooltipState = rememberTooltipState()
|
||||||
|
val localHaptic = LocalHapticFeedback.current
|
||||||
|
|
||||||
|
LaunchedEffect(tooltipState.isVisible) {
|
||||||
|
if (tooltipState.isVisible && haptic) {
|
||||||
|
localHaptic.performHapticFeedback(hapticFeedbackType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TooltipBox(
|
||||||
|
modifier = modifier,
|
||||||
|
positionProvider = positionProvider,
|
||||||
|
tooltip = { PlainTooltip { Text(tooltip) } },
|
||||||
|
state = tooltipState,
|
||||||
|
content = content,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps a composable with a tooltip.
|
||||||
|
*
|
||||||
|
* @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]
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
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 localHaptic = LocalHapticFeedback.current
|
||||||
|
|
||||||
|
LaunchedEffect(tooltipState.isVisible) {
|
||||||
|
if (tooltipState.isVisible && haptic) {
|
||||||
|
localHaptic.performHapticFeedback(hapticFeedbackType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TooltipBox(
|
||||||
|
modifier = modifier,
|
||||||
|
positionProvider = positionProvider,
|
||||||
|
tooltip = { PlainTooltip { Text(stringResource(tooltip)) } },
|
||||||
|
state = tooltipState,
|
||||||
|
content = content,
|
||||||
|
)
|
||||||
|
}
|
@ -16,7 +16,6 @@ import androidx.compose.material.icons.outlined.Search
|
|||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
@ -44,6 +43,7 @@ import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
|||||||
import app.revanced.manager.ui.component.LoadingIndicator
|
import app.revanced.manager.ui.component.LoadingIndicator
|
||||||
import app.revanced.manager.ui.component.NonSuggestedVersionDialog
|
import app.revanced.manager.ui.component.NonSuggestedVersionDialog
|
||||||
import app.revanced.manager.ui.component.SearchView
|
import app.revanced.manager.ui.component.SearchView
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
import app.revanced.manager.ui.model.SelectedApp
|
import app.revanced.manager.ui.model.SelectedApp
|
||||||
import app.revanced.manager.ui.viewmodel.AppSelectorViewModel
|
import app.revanced.manager.ui.viewmodel.AppSelectorViewModel
|
||||||
import app.revanced.manager.util.APK_MIMETYPE
|
import app.revanced.manager.util.APK_MIMETYPE
|
||||||
@ -162,8 +162,15 @@ fun AppSelectorScreen(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = { search = true }) {
|
TooltipIconButton(
|
||||||
Icon(Icons.Outlined.Search, stringResource(R.string.search))
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.search_patches),
|
||||||
|
onClick = { search = true }
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.Search,
|
||||||
|
stringResource(R.string.search)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -62,12 +62,13 @@ import app.revanced.manager.ui.component.AlertDialogExtended
|
|||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
import app.revanced.manager.ui.component.AutoUpdatesDialog
|
||||||
import app.revanced.manager.ui.component.AvailableUpdateDialog
|
import app.revanced.manager.ui.component.AvailableUpdateDialog
|
||||||
import app.revanced.manager.ui.component.NotificationCard
|
|
||||||
import app.revanced.manager.ui.component.ConfirmDialog
|
import app.revanced.manager.ui.component.ConfirmDialog
|
||||||
|
import app.revanced.manager.ui.component.NotificationCard
|
||||||
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
import app.revanced.manager.ui.component.bundle.BundleTopBar
|
||||||
import app.revanced.manager.ui.component.bundle.ImportPatchBundleDialog
|
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.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.ui.viewmodel.DashboardViewModel
|
||||||
import app.revanced.manager.util.RequestInstallAppsContract
|
import app.revanced.manager.util.RequestInstallAppsContract
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
@ -183,21 +184,25 @@ fun DashboardScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
showDeleteConfirmationDialog = true
|
showDeleteConfirmationDialog = true
|
||||||
}
|
},
|
||||||
|
tooltip = stringResource(R.string.delete),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.DeleteOutline,
|
Icons.Outlined.DeleteOutline,
|
||||||
stringResource(R.string.delete)
|
stringResource(R.string.delete)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
vm.selectedSources.forEach { vm.update(it) }
|
vm.selectedSources.forEach { vm.update(it) }
|
||||||
vm.cancelSourceSelection()
|
vm.cancelSourceSelection()
|
||||||
}
|
},
|
||||||
|
tooltip = stringResource(R.string.refresh),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.Refresh,
|
Icons.Outlined.Refresh,
|
||||||
@ -211,8 +216,10 @@ fun DashboardScreen(
|
|||||||
title = stringResource(R.string.app_name),
|
title = stringResource(R.string.app_name),
|
||||||
actions = {
|
actions = {
|
||||||
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
|
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = onUpdateClick,
|
onClick = onUpdateClick,
|
||||||
|
tooltip = stringResource(R.string.update),
|
||||||
) {
|
) {
|
||||||
BadgedBox(
|
BadgedBox(
|
||||||
badge = {
|
badge = {
|
||||||
@ -223,8 +230,18 @@ fun DashboardScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IconButton(onClick = onSettingsClick) {
|
TooltipIconButton(
|
||||||
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
modifier = Modifier,
|
||||||
|
onClick = onSettingsClick,
|
||||||
|
tooltip = stringResource(R.string.settings),
|
||||||
|
) {
|
||||||
|
BadgedBox(
|
||||||
|
badge = {
|
||||||
|
Badge(modifier = Modifier.size(6.dp))
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
applyContainerColor = true
|
applyContainerColor = true
|
||||||
@ -232,7 +249,9 @@ fun DashboardScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
HapticFloatingActionButton(
|
TooltipFloatingActionButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.add),
|
||||||
onClick = {
|
onClick = {
|
||||||
vm.cancelSourceSelection()
|
vm.cancelSourceSelection()
|
||||||
|
|
||||||
@ -245,11 +264,11 @@ fun DashboardScreen(
|
|||||||
DashboardPage.BUNDLES.ordinal
|
DashboardPage.BUNDLES.ordinal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@HapticFloatingActionButton
|
return@TooltipFloatingActionButton
|
||||||
}
|
}
|
||||||
if (vm.android11BugActive) {
|
if (vm.android11BugActive) {
|
||||||
showAndroid11Dialog = true
|
showAndroid11Dialog = true
|
||||||
return@HapticFloatingActionButton
|
return@TooltipFloatingActionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
onAppSelectorClick()
|
onAppSelectorClick()
|
||||||
|
@ -25,7 +25,6 @@ import androidx.compose.material3.AlertDialog
|
|||||||
import androidx.compose.material3.BottomAppBar
|
import androidx.compose.material3.BottomAppBar
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.LinearProgressIndicator
|
import androidx.compose.material3.LinearProgressIndicator
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
@ -51,6 +50,7 @@ import app.revanced.manager.ui.component.InstallerStatusDialog
|
|||||||
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
||||||
import app.revanced.manager.ui.component.patcher.InstallPickerDialog
|
import app.revanced.manager.ui.component.patcher.InstallPickerDialog
|
||||||
import app.revanced.manager.ui.component.patcher.Steps
|
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.model.StepCategory
|
||||||
import app.revanced.manager.ui.viewmodel.PatcherViewModel
|
import app.revanced.manager.ui.viewmodel.PatcherViewModel
|
||||||
import app.revanced.manager.util.APK_MIMETYPE
|
import app.revanced.manager.util.APK_MIMETYPE
|
||||||
@ -164,15 +164,19 @@ fun PatcherScreen(
|
|||||||
bottomBar = {
|
bottomBar = {
|
||||||
BottomAppBar(
|
BottomAppBar(
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = { exportApkLauncher.launch("${viewModel.packageName}_${viewModel.version}_revanced_patched.apk") },
|
onClick = { exportApkLauncher.launch("${viewModel.packageName}_${viewModel.version}_revanced_patched.apk") },
|
||||||
enabled = patcherSucceeded == true
|
enabled = patcherSucceeded == true,
|
||||||
|
tooltip = stringResource(R.string.save_apk),
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk))
|
Icon(Icons.Outlined.Save, stringResource(id = R.string.save_apk))
|
||||||
}
|
}
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = { viewModel.exportLogs(context) },
|
onClick = { viewModel.exportLogs(context) },
|
||||||
enabled = patcherSucceeded != null
|
enabled = patcherSucceeded != null,
|
||||||
|
tooltip = stringResource(R.string.save_logs),
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs))
|
Icon(Icons.Outlined.PostAdd, stringResource(id = R.string.save_logs))
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.material3.ModalBottomSheet
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.ScrollableTabRow
|
import androidx.compose.material3.ScrollableTabRow
|
||||||
import androidx.compose.material3.SmallFloatingActionButton
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
@ -73,6 +72,9 @@ import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
|||||||
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
import app.revanced.manager.ui.component.haptics.HapticExtendedFloatingActionButton
|
||||||
import app.revanced.manager.ui.component.haptics.HapticTab
|
import app.revanced.manager.ui.component.haptics.HapticTab
|
||||||
import app.revanced.manager.ui.component.patches.OptionItem
|
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.component.tooltip.TooltipSmallFloatingActionButton
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
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_INCOMPATIBLE
|
||||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_UNIVERSAL
|
||||||
@ -259,14 +261,16 @@ fun PatchesSelectorScreen(
|
|||||||
animationSpec = tween(durationMillis = 400, easing = EaseInOut),
|
animationSpec = tween(durationMillis = 400, easing = EaseInOut),
|
||||||
label = "SearchBar back button"
|
label = "SearchBar back button"
|
||||||
)
|
)
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier.rotate(rotation),
|
||||||
onClick = {
|
onClick = {
|
||||||
if (searchExpanded) {
|
if (searchExpanded) {
|
||||||
setSearchExpanded(false)
|
setSearchExpanded(false)
|
||||||
} else {
|
} else {
|
||||||
onBackClick()
|
onBackClick()
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
tooltip = stringResource(R.string.back),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
modifier = Modifier.rotate(rotation),
|
modifier = Modifier.rotate(rotation),
|
||||||
@ -282,9 +286,11 @@ fun PatchesSelectorScreen(
|
|||||||
transitionSpec = { fadeIn() togetherWith fadeOut() }
|
transitionSpec = { fadeIn() togetherWith fadeOut() }
|
||||||
) { searchExpanded ->
|
) { searchExpanded ->
|
||||||
if (searchExpanded) {
|
if (searchExpanded) {
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
onClick = { setQuery("") },
|
onClick = { setQuery("") },
|
||||||
enabled = query.isNotEmpty()
|
enabled = query.isNotEmpty(),
|
||||||
|
tooltip = stringResource(R.string.clear),
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Close,
|
imageVector = Icons.Filled.Close,
|
||||||
@ -292,7 +298,11 @@ fun PatchesSelectorScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IconButton(onClick = { showBottomSheet = true }) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
onClick = { showBottomSheet = true },
|
||||||
|
tooltip = stringResource(R.string.more),
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.FilterList,
|
imageVector = Icons.Outlined.FilterList,
|
||||||
contentDescription = stringResource(R.string.more)
|
contentDescription = stringResource(R.string.more)
|
||||||
@ -354,7 +364,20 @@ fun PatchesSelectorScreen(
|
|||||||
horizontalAlignment = Alignment.End,
|
horizontalAlignment = Alignment.End,
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
SmallFloatingActionButton(
|
TooltipSmallFloatingActionButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.more),
|
||||||
|
onClick = { showBottomSheet = true },
|
||||||
|
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.FilterList,
|
||||||
|
contentDescription = stringResource(R.string.more)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TooltipSmallFloatingActionButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.reset),
|
||||||
onClick = viewModel::reset,
|
onClick = viewModel::reset,
|
||||||
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
||||||
) {
|
) {
|
||||||
@ -517,6 +540,7 @@ private fun PatchItem(
|
|||||||
supportingContent = patch.description?.let { { Text(it) } },
|
supportingContent = patch.description?.let { { Text(it) } },
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
if (patch.options?.isNotEmpty() == true) {
|
if (patch.options?.isNotEmpty() == true) {
|
||||||
|
// TODO: Determine if this button should be [TooltipWrap]
|
||||||
IconButton(onClick = onOptionsDialog, enabled = compatible) {
|
IconButton(onClick = onOptionsDialog, enabled = compatible) {
|
||||||
Icon(Icons.Outlined.Settings, null)
|
Icon(Icons.Outlined.Settings, null)
|
||||||
}
|
}
|
||||||
@ -540,7 +564,11 @@ fun ListHeader(
|
|||||||
},
|
},
|
||||||
trailingContent = onHelpClick?.let {
|
trailingContent = onHelpClick?.let {
|
||||||
{
|
{
|
||||||
IconButton(onClick = it) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.help),
|
||||||
|
onClick = it
|
||||||
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.AutoMirrored.Outlined.HelpOutline,
|
Icons.AutoMirrored.Outlined.HelpOutline,
|
||||||
stringResource(R.string.help)
|
stringResource(R.string.help)
|
||||||
@ -619,7 +647,11 @@ private fun OptionsDialog(
|
|||||||
title = patch.name,
|
title = patch.name,
|
||||||
onBackClick = onDismissRequest,
|
onBackClick = onDismissRequest,
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = reset) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.reset),
|
||||||
|
onClick = reset
|
||||||
|
) {
|
||||||
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ import androidx.compose.material.icons.outlined.MailOutline
|
|||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedCard
|
import androidx.compose.material3.OutlinedCard
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
@ -50,6 +49,7 @@ import app.revanced.manager.network.dto.ReVancedSocial
|
|||||||
import app.revanced.manager.ui.component.AppTopBar
|
import app.revanced.manager.ui.component.AppTopBar
|
||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
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.model.navigation.Settings
|
||||||
import app.revanced.manager.ui.viewmodel.AboutViewModel
|
import app.revanced.manager.ui.viewmodel.AboutViewModel
|
||||||
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.DEVELOPER_OPTIONS_TAPS
|
import app.revanced.manager.ui.viewmodel.AboutViewModel.Companion.DEVELOPER_OPTIONS_TAPS
|
||||||
@ -252,9 +252,10 @@ fun AboutSettingsScreen(
|
|||||||
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
|
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)
|
||||||
) {
|
) {
|
||||||
socialButtons.forEach { (icon, text, onClick) ->
|
socialButtons.forEach { (icon, text, onClick) ->
|
||||||
IconButton(
|
TooltipIconButton(
|
||||||
onClick = onClick,
|
|
||||||
modifier = Modifier.padding(end = 8.dp),
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
|
tooltip = text,
|
||||||
|
onClick = onClick
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
icon,
|
icon,
|
||||||
|
@ -21,7 +21,6 @@ import androidx.compose.material.icons.outlined.Restore
|
|||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
@ -52,6 +51,7 @@ import app.revanced.manager.ui.component.settings.BooleanItem
|
|||||||
import app.revanced.manager.ui.component.settings.IntegerItem
|
import app.revanced.manager.ui.component.settings.IntegerItem
|
||||||
import app.revanced.manager.ui.component.settings.SafeguardBooleanItem
|
import app.revanced.manager.ui.component.settings.SafeguardBooleanItem
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
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.ui.viewmodel.AdvancedSettingsViewModel
|
||||||
import app.revanced.manager.util.toast
|
import app.revanced.manager.util.toast
|
||||||
import app.revanced.manager.util.withHapticFeedback
|
import app.revanced.manager.util.withHapticFeedback
|
||||||
@ -243,7 +243,11 @@ private fun APIUrlDialog(currentUrl: String, defaultUrl: String, onSubmit: (Stri
|
|||||||
onValueChange = { url = it },
|
onValueChange = { url = it },
|
||||||
label = { Text(stringResource(R.string.api_url)) },
|
label = { Text(stringResource(R.string.api_url)) },
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
IconButton(onClick = { url = defaultUrl }) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.api_url_dialog_reset),
|
||||||
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import androidx.compose.foundation.lazy.items
|
|||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.outlined.Delete
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
|
import androidx.compose.material.icons.outlined.Search
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@ -45,8 +46,10 @@ import app.revanced.manager.ui.component.ExceptionViewerDialog
|
|||||||
import app.revanced.manager.ui.component.GroupHeader
|
import app.revanced.manager.ui.component.GroupHeader
|
||||||
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
||||||
import app.revanced.manager.ui.component.ConfirmDialog
|
import app.revanced.manager.ui.component.ConfirmDialog
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipWrap
|
||||||
import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
import app.revanced.manager.ui.component.haptics.HapticCheckbox
|
||||||
import app.revanced.manager.ui.component.settings.SettingsListItem
|
import app.revanced.manager.ui.component.settings.SettingsListItem
|
||||||
|
import app.revanced.manager.ui.component.tooltip.TooltipIconButton
|
||||||
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
|
import app.revanced.manager.ui.viewmodel.DownloadsViewModel
|
||||||
import org.koin.androidx.compose.koinViewModel
|
import org.koin.androidx.compose.koinViewModel
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
@ -81,7 +84,11 @@ fun DownloadsSettingsScreen(
|
|||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
actions = {
|
actions = {
|
||||||
if (viewModel.appSelection.isNotEmpty()) {
|
if (viewModel.appSelection.isNotEmpty()) {
|
||||||
IconButton(onClick = { showDeleteConfirmationDialog = true }) {
|
TooltipIconButton(
|
||||||
|
modifier = Modifier,
|
||||||
|
tooltip = stringResource(R.string.delete),
|
||||||
|
onClick = { showDeleteConfirmationDialog = true }
|
||||||
|
) {
|
||||||
Icon(Icons.Default.Delete, stringResource(R.string.delete))
|
Icon(Icons.Default.Delete, stringResource(R.string.delete))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user