mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2026-01-18 00:33:58 +00:00
Compare commits
12 Commits
feat/toolt
...
build/opti
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e9a564e53 | ||
|
|
c9fbc8eb46 | ||
|
|
9b4cea074e | ||
|
|
c68c493781 | ||
|
|
6c4003a21b | ||
|
|
797777d214 | ||
|
|
ba9955addb | ||
|
|
2cdb027e60 | ||
|
|
079ae38330 | ||
|
|
4b22de012c | ||
|
|
66a7f0d60e | ||
|
|
5f77d644df |
11
.github/workflows/build_pull_request.yml
vendored
11
.github/workflows/build_pull_request.yml
vendored
@@ -5,6 +5,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
|
- compose-dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
@@ -12,12 +13,16 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
|
- name: Setup Java
|
||||||
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
distribution: 'temurin'
|
||||||
|
java-version: '17'
|
||||||
|
|
||||||
- name: Cache Gradle
|
- name: Cache Gradle
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v3
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
|
|||||||
2
.github/workflows/open_pull_request.yml
vendored
2
.github/workflows/open_pull_request.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
|
|
||||||
- name: Open pull request
|
- name: Open pull request
|
||||||
uses: repo-sync/pull-request@v2
|
uses: repo-sync/pull-request@v2
|
||||||
|
|||||||
14
.github/workflows/release.yml
vendored
14
.github/workflows/release.yml
vendored
@@ -17,18 +17,16 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup Java
|
- name: Setup Java
|
||||||
uses: actions/setup-java@v4
|
uses: actions/setup-java@v5
|
||||||
with:
|
with:
|
||||||
distribution: 'temurin'
|
distribution: 'temurin'
|
||||||
java-version: '17'
|
java-version: '17'
|
||||||
|
|
||||||
- name: Cache Gradle
|
- name: Cache Gradle
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v3
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
env:
|
env:
|
||||||
@@ -36,7 +34,7 @@ jobs:
|
|||||||
run: ./gradlew assembleRelease
|
run: ./gradlew assembleRelease
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v5
|
||||||
with:
|
with:
|
||||||
node-version: "lts/*"
|
node-version: "lts/*"
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
@@ -56,7 +54,7 @@ jobs:
|
|||||||
echo "${{ secrets.KEYSTORE }}" | base64 --decode > "app/keystore.jks"
|
echo "${{ secrets.KEYSTORE }}" | base64 --decode > "app/keystore.jks"
|
||||||
|
|
||||||
- name: Semantic Release
|
- name: Semantic Release
|
||||||
uses: cycjimmy/semantic-release-action@v4
|
uses: cycjimmy/semantic-release-action@v5
|
||||||
id: semantic
|
id: semantic
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -66,7 +64,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Attest
|
- name: Attest
|
||||||
if: steps.semantic.outputs.new_release_published == 'true'
|
if: steps.semantic.outputs.new_release_published == 'true'
|
||||||
uses: actions/attest-build-provenance@v2
|
uses: actions/attest-build-provenance@v3
|
||||||
with:
|
with:
|
||||||
subject-name: 'ReVanced Manager ${{ steps.release.outputs.new_release_git_tag }}'
|
subject-name: 'ReVanced Manager ${{ steps.release.outputs.new_release_git_tag }}'
|
||||||
subject-path: app/build/outputs/apk/release/revanced-manager*.apk
|
subject-path: app/build/outputs/apk/release/revanced-manager*.apk
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -58,7 +59,7 @@ tasks.matching { it.name.startsWith("publish") }.configureEach {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "app.revanced.manager.plugin.downloader"
|
namespace = "app.revanced.manager.plugin.downloader"
|
||||||
compileSdk = 35
|
compileSdk = 36
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
@@ -81,8 +82,10 @@ android {
|
|||||||
targetCompatibility = JavaVersion.VERSION_17
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlin {
|
||||||
jvmTarget = "17"
|
compilerOptions {
|
||||||
|
jvmTarget = JvmTarget.fromTarget("17")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -52,7 +53,6 @@ dependencies {
|
|||||||
// Room
|
// Room
|
||||||
implementation(libs.room.runtime)
|
implementation(libs.room.runtime)
|
||||||
implementation(libs.room.ktx)
|
implementation(libs.room.ktx)
|
||||||
annotationProcessor(libs.room.compiler)
|
|
||||||
ksp(libs.room.compiler)
|
ksp(libs.room.compiler)
|
||||||
|
|
||||||
// ReVanced
|
// ReVanced
|
||||||
@@ -60,7 +60,7 @@ dependencies {
|
|||||||
implementation(libs.revanced.library)
|
implementation(libs.revanced.library)
|
||||||
|
|
||||||
// Downloader plugins
|
// Downloader plugins
|
||||||
implementation(project(":api"))
|
implementation(projects.api)
|
||||||
|
|
||||||
// Native processes
|
// Native processes
|
||||||
implementation(libs.kotlin.process)
|
implementation(libs.kotlin.process)
|
||||||
@@ -111,19 +111,21 @@ dependencies {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "app.revanced.manager"
|
namespace = "app.revanced.manager"
|
||||||
compileSdk = 35
|
compileSdk = 36
|
||||||
buildToolsVersion = "35.0.1"
|
buildToolsVersion = "36.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "app.revanced.manager"
|
applicationId = "app.revanced.manager"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "0.0.1"
|
versionName = "0.0.1"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
configureEach {
|
||||||
|
}
|
||||||
debug {
|
debug {
|
||||||
applicationIdSuffix = ".debug"
|
applicationIdSuffix = ".debug"
|
||||||
resValue("string", "app_name", "ReVanced Manager (Debug)")
|
resValue("string", "app_name", "ReVanced Manager (Debug)")
|
||||||
@@ -199,8 +201,11 @@ android {
|
|||||||
arg("room.schemaLocation", "$projectDir/schemas")
|
arg("room.schemaLocation", "$projectDir/schemas")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlin {
|
||||||
jvmTarget = "17"
|
compilerOptions {
|
||||||
|
jvmTarget = JvmTarget.fromTarget("17")
|
||||||
|
jvmToolchain(17)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
@@ -223,10 +228,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
|
||||||
jvmToolchain(17)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
// Needed by gradle-semantic-release-plugin.
|
// Needed by gradle-semantic-release-plugin.
|
||||||
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
|
// Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
|
||||||
|
|||||||
65
app/proguard-rules.pro
vendored
65
app/proguard-rules.pro
vendored
@@ -1,63 +1,14 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.kts.kts.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
-dontobfuscate
|
-dontobfuscate
|
||||||
|
|
||||||
# Required for serialization to work properly
|
-keep class app.revanced.manager.patcher.runtime.process.* { *; }
|
||||||
-if @kotlinx.serialization.Serializable class **
|
-keep class app.revanced.manager.plugin.** { *; }
|
||||||
-keepclassmembers class <1> {
|
-keep class app.revanced.patcher.** { *; }
|
||||||
static <1>$Companion Companion;
|
-keep class com.android.tools.smali.** { *; }
|
||||||
}
|
-keep class kotlin.** { *; }
|
||||||
-if @kotlinx.serialization.Serializable class ** {
|
-keepnames class com.android.apksig.internal.** { *; }
|
||||||
static **$* *;
|
-keepnames class org.xmlpull.** { *; }
|
||||||
}
|
|
||||||
-keepclassmembers class <2>$<3> {
|
|
||||||
kotlinx.serialization.KSerializer serializer(...);
|
|
||||||
}
|
|
||||||
-if @kotlinx.serialization.Serializable class ** {
|
|
||||||
public static ** INSTANCE;
|
|
||||||
}
|
|
||||||
-keepclassmembers class <1> {
|
|
||||||
public static <1> INSTANCE;
|
|
||||||
kotlinx.serialization.KSerializer serializer(...);
|
|
||||||
}
|
|
||||||
|
|
||||||
# This required for the process runtime.
|
-dontwarn com.google.j2objc.annotations.*
|
||||||
-keep class app.revanced.manager.patcher.runtime.process.* {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
# Required for the patcher to function correctly
|
|
||||||
-keep class app.revanced.patcher.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class brut.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class org.xmlpull.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class kotlin.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class org.jf.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class com.android.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
-keep class app.revanced.manager.plugin.** {
|
|
||||||
*;
|
|
||||||
}
|
|
||||||
|
|
||||||
-dontwarn com.google.auto.value.**
|
|
||||||
-dontwarn java.awt.**
|
-dontwarn java.awt.**
|
||||||
-dontwarn javax.**
|
-dontwarn javax.**
|
||||||
-dontwarn org.slf4j.**
|
-dontwarn org.slf4j.**
|
||||||
-dontwarn it.skrape.fetcher.*
|
|
||||||
-dontwarn com.google.j2objc.annotations.*
|
|
||||||
|
|
||||||
-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
|
|
||||||
@@ -16,8 +16,12 @@ import io.ktor.http.isSuccess
|
|||||||
import io.ktor.utils.io.ByteReadChannel
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
import io.ktor.utils.io.core.isNotEmpty
|
import io.ktor.utils.io.core.isNotEmpty
|
||||||
import io.ktor.utils.io.core.readBytes
|
import io.ktor.utils.io.core.readBytes
|
||||||
|
import io.ktor.utils.io.core.remaining
|
||||||
|
import io.ktor.utils.io.exhausted
|
||||||
|
import io.ktor.utils.io.readRemaining
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlinx.io.asSink
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
@@ -69,14 +73,14 @@ class HttpService(
|
|||||||
) {
|
) {
|
||||||
http.prepareGet(builder).execute { httpResponse ->
|
http.prepareGet(builder).execute { httpResponse ->
|
||||||
if (httpResponse.status.isSuccess()) {
|
if (httpResponse.status.isSuccess()) {
|
||||||
|
val stream = outputStream.asSink()
|
||||||
val channel: ByteReadChannel = httpResponse.body()
|
val channel: ByteReadChannel = httpResponse.body()
|
||||||
withContext(Dispatchers.IO) {
|
var count = 0L
|
||||||
while (!channel.isClosedForRead) {
|
stream.use {
|
||||||
val packet = channel.readRemaining(DEFAULT_BUFFER_SIZE.toLong())
|
while (!channel.exhausted()) {
|
||||||
while (packet.isNotEmpty) {
|
val chunk = channel.readRemaining()
|
||||||
val bytes = packet.readBytes()
|
count += chunk.remaining
|
||||||
outputStream.write(bytes)
|
chunk.transferTo(stream)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ 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
|
||||||
@@ -21,7 +22,6 @@ 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,10 +69,7 @@ fun AppTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onBackClick) {
|
||||||
onClick = onBackClick,
|
|
||||||
tooltip = stringResource(R.string.back),
|
|
||||||
) {
|
|
||||||
backIcon()
|
backIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -111,10 +108,7 @@ fun AppTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onBackClick) {
|
||||||
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,11 +27,7 @@ fun ArrowButton(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onClick?.let {
|
onClick?.let {
|
||||||
TooltipIconButton(
|
IconButton(onClick = it) {
|
||||||
modifier = Modifier,
|
|
||||||
onClick = it,
|
|
||||||
tooltip = stringResource(description),
|
|
||||||
) {
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.KeyboardArrowUp,
|
imageVector = Icons.Filled.KeyboardArrowUp,
|
||||||
contentDescription = stringResource(description),
|
contentDescription = stringResource(description),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ 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
|
||||||
@@ -17,7 +18,6 @@ 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,8 +39,7 @@ fun ExceptionViewerDialog(text: String, onDismiss: () -> Unit) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
modifier = Modifier,
|
|
||||||
onClick = {
|
onClick = {
|
||||||
val sendIntent: Intent = Intent().apply {
|
val sendIntent: Intent = Intent().apply {
|
||||||
action = Intent.ACTION_SEND
|
action = Intent.ACTION_SEND
|
||||||
@@ -53,8 +52,7 @@ 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,
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package app.revanced.manager.ui.component
|
|||||||
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.text.TextLinkStyles
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
import com.mikepenz.markdown.compose.Markdown
|
import com.mikepenz.markdown.compose.Markdown
|
||||||
import com.mikepenz.markdown.m3.markdownColor
|
import com.mikepenz.markdown.m3.markdownColor
|
||||||
import com.mikepenz.markdown.m3.markdownTypography
|
import com.mikepenz.markdown.m3.markdownTypography
|
||||||
@@ -18,15 +20,29 @@ fun Markdown(
|
|||||||
colors = markdownColor(
|
colors = markdownColor(
|
||||||
text = MaterialTheme.colorScheme.onSurfaceVariant,
|
text = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
codeBackground = MaterialTheme.colorScheme.secondaryContainer,
|
codeBackground = MaterialTheme.colorScheme.secondaryContainer,
|
||||||
codeText = MaterialTheme.colorScheme.onSecondaryContainer,
|
|
||||||
linkText = MaterialTheme.colorScheme.primary
|
|
||||||
),
|
),
|
||||||
typography = markdownTypography(
|
typography = markdownTypography(
|
||||||
h1 = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.Bold),
|
h1 = MaterialTheme.typography.headlineSmall.copy(fontWeight = FontWeight.Bold),
|
||||||
h2 = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Bold),
|
h2 = MaterialTheme.typography.titleLarge.copy(fontWeight = FontWeight.Bold),
|
||||||
h3 = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
|
h3 = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold),
|
||||||
text = MaterialTheme.typography.bodyMedium,
|
text = MaterialTheme.typography.bodyMedium,
|
||||||
list = MaterialTheme.typography.bodyMedium
|
code = markdownTypography().code.copy(color = MaterialTheme.colorScheme.onSecondaryContainer),
|
||||||
|
list = MaterialTheme.typography.bodyMedium,
|
||||||
|
textLink = TextLinkStyles(
|
||||||
|
style = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
fontWeight = FontWeight.Bold, textDecoration = TextDecoration.Underline,
|
||||||
|
color = MaterialTheme.colorScheme.primary
|
||||||
|
).toSpanStyle(),
|
||||||
|
hoveredStyle = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
fontWeight = FontWeight.Bold, textDecoration = TextDecoration.Underline,
|
||||||
|
color = MaterialTheme.colorScheme.secondary
|
||||||
|
).toSpanStyle(),
|
||||||
|
pressedStyle = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
fontWeight = FontWeight.Bold, textDecoration = TextDecoration.Underline,
|
||||||
|
color = MaterialTheme.colorScheme.tertiary
|
||||||
|
).toSpanStyle()
|
||||||
|
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,7 @@ 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
|
||||||
@@ -24,7 +25,6 @@ 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,10 +138,7 @@ fun NotificationCard(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (onDismiss != null) {
|
if (onDismiss != null) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onDismiss) {
|
||||||
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,6 +5,7 @@ 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
|
||||||
@@ -18,7 +19,6 @@ 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,15 +33,9 @@ fun PasswordField(modifier: Modifier = Modifier, value: String, onValueChange: (
|
|||||||
label = label,
|
label = label,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = {
|
||||||
modifier = Modifier,
|
visible = !visible
|
||||||
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,6 +5,7 @@ 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
|
||||||
@@ -18,7 +19,6 @@ 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,10 +48,7 @@ fun SearchView(
|
|||||||
onExpandedChange = onActiveChange,
|
onExpandedChange = onActiveChange,
|
||||||
placeholder = placeholder,
|
placeholder = placeholder,
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { onActiveChange(false) }) {
|
||||||
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)
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ import app.revanced.manager.domain.repository.PatchBundleRepository
|
|||||||
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
import app.revanced.manager.ui.component.ColumnWithScrollbar
|
||||||
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 app.revanced.manager.ui.component.TextInputDialog
|
import app.revanced.manager.ui.component.TextInputDialog
|
||||||
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
import app.revanced.manager.ui.component.haptics.HapticSwitch
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -104,11 +103,7 @@ fun BundleInformationDialog(
|
|||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (!src.isDefault) {
|
if (!src.isDefault) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onDeleteRequest) {
|
||||||
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)
|
||||||
@@ -116,11 +111,7 @@ fun BundleInformationDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isLocal && hasNetwork) {
|
if (!isLocal && hasNetwork) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onUpdate) {
|
||||||
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,6 +2,7 @@ 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
|
||||||
@@ -9,11 +10,7 @@ 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
|
||||||
@@ -36,10 +33,7 @@ fun BundleTopBar(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
if (onBackClick != null) {
|
if (onBackClick != null) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = onBackClick) {
|
||||||
tooltip = stringResource(R.string.back),
|
|
||||||
onClick = onBackClick
|
|
||||||
) {
|
|
||||||
backIcon()
|
backIcon()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,7 +193,6 @@ private 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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -67,7 +67,6 @@ 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
|
||||||
@@ -124,11 +123,7 @@ private interface OptionEditor<T : Any> {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
fun ListItemTrailingContent(scope: OptionEditorScope<T>) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { scope.checkSafeguard { clickAction(scope) } }) {
|
||||||
modifier = Modifier,
|
|
||||||
tooltip = stringResource(R.string.edit),
|
|
||||||
onClick = { scope.checkSafeguard { clickAction(scope) } }
|
|
||||||
) {
|
|
||||||
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
Icon(Icons.Outlined.Edit, stringResource(R.string.edit))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,9 +270,7 @@ private object StringOptionEditor : OptionEditor<String> {
|
|||||||
},
|
},
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
|
var showDropdownMenu by rememberSaveable { mutableStateOf(false) }
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
modifier = Modifier,
|
|
||||||
tooltip = stringResource(R.string.string_option_menu_description),
|
|
||||||
onClick = { showDropdownMenu = true }
|
onClick = { showDropdownMenu = true }
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
@@ -587,9 +580,7 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (deleteMode) {
|
if (deleteMode) {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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 })
|
||||||
@@ -600,9 +591,7 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
stringResource(R.string.select_deselect_all)
|
stringResource(R.string.select_deselect_all)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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()
|
||||||
@@ -615,15 +604,8 @@ private class ListOptionEditor<T : Serializable>(private val elementEditor: Opti
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TooltipIconButton(
|
IconButton(onClick = items::clear) {
|
||||||
modifier = Modifier,
|
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
||||||
tooltip = stringResource(R.string.reset),
|
|
||||||
onClick = items::clear
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Outlined.Restore,
|
|
||||||
stringResource(R.string.reset)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -691,10 +673,9 @@ 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 = {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
|
modifier = Modifier.draggableHandle(interactionSource = interactionSource),
|
||||||
tooltip = stringResource(R.string.delete),
|
onClick = {},
|
||||||
onClick = { }
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Filled.DragHandle,
|
Icons.Filled.DragHandle,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ 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
|
||||||
@@ -16,7 +17,6 @@ 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,14 +65,10 @@ fun IntegerItem(
|
|||||||
headlineContent = stringResource(headline),
|
headlineContent = stringResource(headline),
|
||||||
supportingContent = stringResource(description),
|
supportingContent = stringResource(description),
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { dialogOpen = true }) {
|
||||||
modifier = modifier,
|
|
||||||
onClick = { dialogOpen = true },
|
|
||||||
tooltip = stringResource(R.string.edit),
|
|
||||||
) {
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.Edit,
|
Icons.Outlined.Edit,
|
||||||
contentDescription = stringResource(R.string.edit),
|
contentDescription = stringResource(R.string.edit)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
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(
|
|
||||||
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(
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
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(
|
|
||||||
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(
|
|
||||||
tooltip = tooltip,
|
|
||||||
positionProvider = positionProvider,
|
|
||||||
haptic = haptic,
|
|
||||||
hapticFeedbackType = hapticFeedbackType,
|
|
||||||
) {
|
|
||||||
IconButton(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
enabled = enabled,
|
|
||||||
colors = colors,
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
content = content,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
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(
|
|
||||||
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(
|
|
||||||
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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
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 = 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 = 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,6 +16,7 @@ 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
|
||||||
@@ -43,7 +44,6 @@ 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,14 +162,8 @@ fun AppSelectorScreen(
|
|||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
actions = {
|
actions = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { search = true }) {
|
||||||
tooltip = stringResource(R.string.search_patches),
|
Icon(Icons.Outlined.Search, stringResource(R.string.search))
|
||||||
onClick = { search = true }
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Outlined.Search,
|
|
||||||
stringResource(R.string.search)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -66,9 +66,8 @@ 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.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
|
||||||
@@ -182,20 +181,18 @@ fun DashboardScreen(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
onClick = vm::updateSources,
|
onClick = vm::updateSources
|
||||||
tooltip = stringResource(R.string.refresh)
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
Icons.Outlined.Refresh,
|
Icons.Outlined.Refresh,
|
||||||
@@ -209,9 +206,8 @@ fun DashboardScreen(
|
|||||||
title = stringResource(R.string.app_name),
|
title = stringResource(R.string.app_name),
|
||||||
actions = {
|
actions = {
|
||||||
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
|
if (!vm.updatedManagerVersion.isNullOrEmpty()) {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
onClick = onUpdateClick,
|
onClick = onUpdateClick,
|
||||||
tooltip = stringResource(R.string.update),
|
|
||||||
) {
|
) {
|
||||||
BadgedBox(
|
BadgedBox(
|
||||||
badge = {
|
badge = {
|
||||||
@@ -222,17 +218,8 @@ fun DashboardScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TooltipIconButton(
|
IconButton(onClick = onSettingsClick) {
|
||||||
onClick = onSettingsClick,
|
Icon(Icons.Outlined.Settings, stringResource(R.string.settings))
|
||||||
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
|
||||||
@@ -240,8 +227,7 @@ fun DashboardScreen(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
floatingActionButton = {
|
floatingActionButton = {
|
||||||
TooltipFloatingActionButton(
|
HapticFloatingActionButton(
|
||||||
tooltip = stringResource(R.string.add),
|
|
||||||
onClick = {
|
onClick = {
|
||||||
vm.cancelSourceSelection()
|
vm.cancelSourceSelection()
|
||||||
|
|
||||||
@@ -254,11 +240,11 @@ fun DashboardScreen(
|
|||||||
DashboardPage.BUNDLES.ordinal
|
DashboardPage.BUNDLES.ordinal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return@TooltipFloatingActionButton
|
return@HapticFloatingActionButton
|
||||||
}
|
}
|
||||||
if (vm.android11BugActive) {
|
if (vm.android11BugActive) {
|
||||||
showAndroid11Dialog = true
|
showAndroid11Dialog = true
|
||||||
return@TooltipFloatingActionButton
|
return@HapticFloatingActionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
onAppSelectorClick()
|
onAppSelectorClick()
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ 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
|
||||||
@@ -50,7 +51,6 @@ 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,17 +164,15 @@ fun PatcherScreen(
|
|||||||
bottomBar = {
|
bottomBar = {
|
||||||
BottomAppBar(
|
BottomAppBar(
|
||||||
actions = {
|
actions = {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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))
|
||||||
}
|
}
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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,6 +41,7 @@ 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
|
||||||
@@ -72,9 +73,6 @@ 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.component.patches.SelectionWarningDialog
|
import app.revanced.manager.ui.component.patches.SelectionWarningDialog
|
||||||
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
|
||||||
@@ -261,15 +259,14 @@ fun PatchesSelectorScreen(
|
|||||||
animationSpec = tween(durationMillis = 400, easing = EaseInOut),
|
animationSpec = tween(durationMillis = 400, easing = EaseInOut),
|
||||||
label = "SearchBar back button"
|
label = "SearchBar back button"
|
||||||
)
|
)
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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),
|
||||||
@@ -285,10 +282,9 @@ fun PatchesSelectorScreen(
|
|||||||
transitionSpec = { fadeIn() togetherWith fadeOut() }
|
transitionSpec = { fadeIn() togetherWith fadeOut() }
|
||||||
) { searchExpanded ->
|
) { searchExpanded ->
|
||||||
if (searchExpanded) {
|
if (searchExpanded) {
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
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,
|
||||||
@@ -296,10 +292,7 @@ fun PatchesSelectorScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { showBottomSheet = true }) {
|
||||||
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)
|
||||||
@@ -361,8 +354,7 @@ fun PatchesSelectorScreen(
|
|||||||
horizontalAlignment = Alignment.End,
|
horizontalAlignment = Alignment.End,
|
||||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||||
) {
|
) {
|
||||||
TooltipSmallFloatingActionButton(
|
SmallFloatingActionButton(
|
||||||
tooltip = stringResource(R.string.reset),
|
|
||||||
onClick = viewModel::reset,
|
onClick = viewModel::reset,
|
||||||
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
containerColor = MaterialTheme.colorScheme.tertiaryContainer
|
||||||
) {
|
) {
|
||||||
@@ -514,7 +506,6 @@ 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)
|
||||||
}
|
}
|
||||||
@@ -538,10 +529,7 @@ fun ListHeader(
|
|||||||
},
|
},
|
||||||
trailingContent = onHelpClick?.let {
|
trailingContent = onHelpClick?.let {
|
||||||
{
|
{
|
||||||
TooltipIconButton(
|
IconButton(onClick = it) {
|
||||||
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)
|
||||||
@@ -621,10 +609,7 @@ private fun OptionsDialog(
|
|||||||
title = patch.name,
|
title = patch.name,
|
||||||
onBackClick = onDismissRequest,
|
onBackClick = onDismissRequest,
|
||||||
actions = {
|
actions = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = reset) {
|
||||||
tooltip = stringResource(R.string.reset),
|
|
||||||
onClick = reset
|
|
||||||
) {
|
|
||||||
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
Icon(Icons.Outlined.Restore, stringResource(R.string.reset))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ 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
|
||||||
@@ -49,7 +50,6 @@ 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,10 +252,9 @@ 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) ->
|
||||||
TooltipIconButton(
|
IconButton(
|
||||||
|
onClick = onClick,
|
||||||
modifier = Modifier.padding(end = 8.dp),
|
modifier = Modifier.padding(end = 8.dp),
|
||||||
tooltip = text,
|
|
||||||
onClick = onClick
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ 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
|
||||||
@@ -51,7 +52,6 @@ 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,11 +243,7 @@ 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 = {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { url = defaultUrl }) {
|
||||||
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ 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
|
||||||
@@ -41,10 +40,8 @@ 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
|
||||||
@@ -78,10 +75,7 @@ fun DownloadsSettingsScreen(
|
|||||||
onBackClick = onBackClick,
|
onBackClick = onBackClick,
|
||||||
actions = {
|
actions = {
|
||||||
if (viewModel.appSelection.isNotEmpty()) {
|
if (viewModel.appSelection.isNotEmpty()) {
|
||||||
TooltipIconButton(
|
IconButton(onClick = { showDeleteConfirmationDialog = true }) {
|
||||||
tooltip = stringResource(R.string.delete),
|
|
||||||
onClick = { showDeleteConfirmationDialog = true }
|
|
||||||
) {
|
|
||||||
Icon(Icons.Default.Delete, stringResource(R.string.delete))
|
Icon(Icons.Default.Delete, stringResource(R.string.delete))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ class UpdateViewModel(
|
|||||||
url(release.downloadUrl)
|
url(release.downloadUrl)
|
||||||
onDownload { bytesSentTotal, contentLength ->
|
onDownload { bytesSentTotal, contentLength ->
|
||||||
downloadedSize = bytesSentTotal
|
downloadedSize = bytesSentTotal
|
||||||
totalSize = contentLength
|
totalSize = contentLength ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
installUpdate()
|
installUpdate()
|
||||||
|
|||||||
@@ -42,7 +42,6 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.flatMapLatest
|
import kotlinx.coroutines.flow.flatMapLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.datetime.Clock
|
|
||||||
import kotlinx.datetime.LocalDateTime
|
import kotlinx.datetime.LocalDateTime
|
||||||
import kotlinx.datetime.TimeZone
|
import kotlinx.datetime.TimeZone
|
||||||
import kotlinx.datetime.format.MonthNames
|
import kotlinx.datetime.format.MonthNames
|
||||||
@@ -53,6 +52,7 @@ import java.util.Locale
|
|||||||
import kotlin.properties.PropertyDelegateProvider
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
|
||||||
typealias PatchSelection = Map<Int, Set<String>>
|
typealias PatchSelection = Map<Int, Set<String>>
|
||||||
typealias Options = Map<Int, Map<String, Map<String, Any?>>>
|
typealias Options = Map<Int, Map<String, Map<String, Any?>>>
|
||||||
@@ -141,9 +141,10 @@ suspend fun <T> Flow<Iterable<T>>.collectEach(block: suspend (T) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalTime::class)
|
||||||
fun LocalDateTime.relativeTime(context: Context): String {
|
fun LocalDateTime.relativeTime(context: Context): String {
|
||||||
try {
|
try {
|
||||||
val now = Clock.System.now()
|
val now = kotlin.time.Clock.System.now()
|
||||||
val duration = now - this.toInstant(TimeZone.UTC)
|
val duration = now - this.toInstant(TimeZone.UTC)
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
org.gradle.jvmargs=-Xmx3072m -XX:MaxMetaspaceSize=1024m -Dfile.encoding=UTF-8
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||||
# Android operating system, and which are packaged with your app's APK
|
# Android operating system, and which are packaged with your app's APK
|
||||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
[versions]
|
[versions]
|
||||||
ktx = "1.16.0"
|
ktx = "1.17.0"
|
||||||
material3 = "1.3.2"
|
material3 = "1.3.2"
|
||||||
ui-tooling = "1.8.1"
|
ui-tooling = "1.9.1"
|
||||||
viewmodel-lifecycle = "2.9.0"
|
viewmodel-lifecycle = "2.9.4"
|
||||||
splash-screen = "1.0.1"
|
splash-screen = "1.0.1"
|
||||||
activity = "1.10.1"
|
activity = "1.11.0"
|
||||||
appcompat = "1.7.0"
|
appcompat = "1.7.1"
|
||||||
preferences-datastore = "1.1.2"
|
preferences-datastore = "1.1.7"
|
||||||
work-runtime = "2.10.1"
|
work-runtime = "2.10.4"
|
||||||
compose-bom = "2025.05.00"
|
compose-bom = "2025.09.00"
|
||||||
navigation = "2.8.6"
|
navigation = "2.9.4"
|
||||||
accompanist = "0.37.0"
|
accompanist = "0.37.3"
|
||||||
placeholder = "1.1.2"
|
placeholder = "2.0.0"
|
||||||
reorderable = "2.4.3"
|
reorderable = "2.5.1"
|
||||||
serialization = "1.8.0"
|
serialization = "1.9.0"
|
||||||
collection = "0.3.8"
|
collection = "0.4.0"
|
||||||
datetime = "0.6.1"
|
datetime = "0.7.1"
|
||||||
room-version = "2.7.1"
|
room-version = "2.8.0"
|
||||||
revanced-patcher = "21.0.0"
|
revanced-patcher = "21.0.0"
|
||||||
revanced-library = "3.0.2"
|
revanced-library = "3.0.2"
|
||||||
koin = "3.5.3"
|
koin = "4.1.1"
|
||||||
ktor = "2.3.9"
|
ktor = "3.3.0"
|
||||||
markdown-renderer = "0.30.0"
|
markdown-renderer = "0.37.0"
|
||||||
fading-edges = "1.0.4"
|
fading-edges = "1.0.4"
|
||||||
kotlin = "2.1.10"
|
kotlin = "2.2.20"
|
||||||
android-gradle-plugin = "8.9.1"
|
android-gradle-plugin = "8.13.0"
|
||||||
dev-tools-gradle-plugin = "2.1.10-1.0.29"
|
dev-tools-gradle-plugin = "2.2.20-2.0.2"
|
||||||
about-libraries-gradle-plugin = "12.1.2"
|
about-libraries-gradle-plugin = "12.2.4"
|
||||||
coil = "2.7.0"
|
coil = "2.7.0"
|
||||||
app-icon-loader-coil = "1.5.0"
|
app-icon-loader-coil = "1.5.0"
|
||||||
libsu = "6.0.0"
|
libsu = "6.0.0"
|
||||||
@@ -34,8 +34,8 @@ scrollbars = "1.0.4"
|
|||||||
enumutil = "1.1.1"
|
enumutil = "1.1.1"
|
||||||
compose-icons = "1.2.4"
|
compose-icons = "1.2.4"
|
||||||
kotlin-process = "1.5.1"
|
kotlin-process = "1.5.1"
|
||||||
hidden-api-stub = "4.3.3"
|
hidden-api-stub = "4.4.0"
|
||||||
binary-compatibility-validator = "0.17.0"
|
binary-compatibility-validator = "0.18.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
# AndroidX Core
|
# AndroidX Core
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,7 +1,7 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionSha256Sum=61ad310d3c7d3e5da131b76bbf22b5a4c0786e9d892dae8c1658d4b484de3caa
|
distributionSha256Sum=a17ddd85a26b6a7f5ddb71ff8b05fc5104c0202c6e64782429790c933686c806
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
2
gradlew
vendored
2
gradlew
vendored
@@ -1,7 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright © 2015-2021 the original authors.
|
# Copyright © 2015 the original authors.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -22,5 +22,7 @@ dependencyResolutionManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
|
||||||
rootProject.name = "revanced-manager"
|
rootProject.name = "revanced-manager"
|
||||||
include(":app", ":api")
|
include(":app", ":api")
|
||||||
|
|||||||
Reference in New Issue
Block a user