diff --git a/.gitignore b/.gitignore index bb3ab5e..7d85821 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ -*.iml -.gradle -/local.properties .idea -.DS_Store -build -release +.gradle +.kotlin + +/**/build/ +/local.properties /captures -.externalNativeBuild -.cxx -local.properties + +.DS_Store *.log diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c6efa02..fb6e485 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream plugins { alias(libs.plugins.android.application) + alias(libs.plugins.compose.compiler) alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.parcelize) alias(libs.plugins.kotlin.serialization) @@ -11,11 +12,11 @@ plugins { android { namespace = "com.aliucord.manager" - compileSdk = 34 + compileSdk = 35 defaultConfig { minSdk = 24 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "0.0.1" @@ -117,10 +118,6 @@ android { compose = true } - composeOptions { - kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get() - } - lint { disable += "ModifierParameter" } @@ -129,6 +126,7 @@ android { dependencies { implementation(libs.bundles.accompanist) implementation(libs.bundles.androidx) + implementation(libs.bundles.coil) implementation(libs.bundles.compose) implementation(libs.bundles.koin) implementation(libs.bundles.ktor) @@ -145,7 +143,6 @@ dependencies { implementation(libs.axml) implementation(libs.bouncycastle) implementation(libs.binaryResources) - implementation(libs.coil) implementation(libs.diff) implementation(libs.microg) implementation(libs.smali) diff --git a/app/src/main/kotlin/com/aliucord/manager/ManagerApplication.kt b/app/src/main/kotlin/com/aliucord/manager/ManagerApplication.kt index 749b3b8..9b8a829 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ManagerApplication.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ManagerApplication.kt @@ -17,10 +17,8 @@ import com.aliucord.manager.ui.screens.plugins.PluginsModel import com.aliucord.manager.ui.screens.settings.SettingsModel import com.aliucord.manager.ui.widgets.updater.UpdaterViewModel import org.koin.android.ext.koin.androidContext -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.context.startKoin -import org.koin.core.module.dsl.factoryOf -import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.* import org.koin.dsl.module class ManagerApplication : Application() { diff --git a/app/src/main/kotlin/com/aliucord/manager/patcher/steps/base/Step.kt b/app/src/main/kotlin/com/aliucord/manager/patcher/steps/base/Step.kt index ba3ac7a..6a4e432 100644 --- a/app/src/main/kotlin/com/aliucord/manager/patcher/steps/base/Step.kt +++ b/app/src/main/kotlin/com/aliucord/manager/patcher/steps/base/Step.kt @@ -6,8 +6,8 @@ import com.aliucord.manager.patcher.StepRunner import com.aliucord.manager.patcher.steps.StepGroup import com.aliucord.manager.util.toPrecision import kotlinx.coroutines.* -import org.koin.core.time.measureTimedValue import kotlin.math.roundToLong +import kotlin.time.measureTimedValue /** * A base install process step. Steps are single-use @@ -95,7 +95,7 @@ abstract class Step { startTime = System.currentTimeMillis() // Execute this steps logic while timing it - val (error, executionTimeMs) = measureTimedValue { + val (error, executionTime) = measureTimedValue { try { withContext(Dispatchers.Default) { execute(container) @@ -111,8 +111,8 @@ abstract class Step { } } - totalTimeMs = executionTimeMs.roundToLong() - durationSecs.floatValue = executionTimeMs.toFloat() / 1000f + totalTimeMs = executionTime.inWholeMilliseconds + durationSecs.floatValue = executionTime.inWholeMilliseconds / 1000f return error } diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt index b6fb906..f464648 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/Contributors.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import coil.compose.AsyncImage +import coil3.compose.AsyncImage import com.aliucord.manager.R import com.aliucord.manager.network.dto.GithubUser diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/Theme.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/Theme.kt index 53d8f33..0a69fb2 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/Theme.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/Theme.kt @@ -33,6 +33,9 @@ fun ManagerTheme( false -> LightCustomColors } + // As usual, Google deprecates accompanist libraries and replaces them with an incomplete and shitty replacement in androidx + // enableEdgeToEdge() does not work for our use case. + @Suppress("DEPRECATION") val systemUiController = rememberSystemUiController() SideEffect { diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/components/plugins/Changelog.kt b/app/src/main/kotlin/com/aliucord/manager/ui/components/plugins/Changelog.kt index d51a8ac..1bdd0d9 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/components/plugins/Changelog.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/components/plugins/Changelog.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.text.* import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp -import coil.compose.AsyncImage +import coil3.compose.AsyncImage import com.aliucord.manager.R import com.aliucord.manager.domain.model.Plugin diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt index 7d84cd3..ac8a05b 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/about/AboutScreen.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.koin.getScreenModel -import coil.compose.AsyncImage +import coil3.compose.AsyncImage import com.aliucord.manager.R import com.aliucord.manager.ui.components.* import com.aliucord.manager.ui.util.paddings.PaddingValuesSides @@ -126,7 +126,7 @@ private fun UserEntry(name: String, roles: String, username: String = name) { modifier = Modifier .clickable( onClick = { uriHandler.openUri("https://github.com/$username") }, - indication = rememberRipple(bounded = false, radius = 90.dp), + indication = ripple(bounded = false, radius = 90.dp), interactionSource = remember { MutableInteractionSource() } ) .widthIn(min = 100.dp) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeModel.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeModel.kt index 983802e..d55ee64 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeModel.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeModel.kt @@ -104,30 +104,32 @@ class HomeModel( .asSequence() .filter { val isAliucordPkg = it.packageName == "com.aliucord" - val hasAliucordMeta = it.applicationInfo.metaData?.containsKey("isAliucord") == true + val hasAliucordMeta = it.applicationInfo?.metaData?.containsKey("isAliucord") == true isAliucordPkg || hasAliucordMeta } - val aliucordInstallations = aliucordPackages.map { + val aliucordInstallations = aliucordPackages.mapNotNull { // `longVersionCode` is unnecessary since Discord doesn't use `versionCodeMajor` @Suppress("DEPRECATION") val versionCode = it.versionCode + val versionName = it.versionName ?: return@mapNotNull null + val applicationInfo = it.applicationInfo ?: return@mapNotNull null - val baseVersion = it.applicationInfo.metaData?.getInt("aliucordBaseVersion") + val baseVersion = it.applicationInfo?.metaData?.getInt("aliucordBaseVersion") val isBaseUpdated = /* TODO: remote data json instead */ baseVersion == 0 InstallData( - name = packageManager.getApplicationLabel(it.applicationInfo).toString(), + name = packageManager.getApplicationLabel(applicationInfo).toString(), packageName = it.packageName, baseUpdated = isBaseUpdated, icon = packageManager - .getApplicationIcon(it.applicationInfo) + .getApplicationIcon(applicationInfo) .toBitmap() .asImageBitmap() .let(::BitmapPainter), version = DiscordVersion.Existing( type = DiscordVersion.parseVersionType(versionCode), - name = it.versionName.split("-")[0].trim(), + name = versionName.split("-")[0].trim(), code = versionCode, ), ) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt index 078b1cf..915a9f0 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/home/HomeScreen.kt @@ -43,7 +43,7 @@ class HomeScreen : Screen { val model = getScreenModel() // Refresh installations list when the screen changes or activity resumes - LifecycleResumeEffect { + LifecycleResumeEffect(key1 = "INSTALLATIONS_REFRESH") { model.fetchInstallations() onPauseOrDispose {} diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/screens/plugins/PluginsScreen.kt b/app/src/main/kotlin/com/aliucord/manager/ui/screens/plugins/PluginsScreen.kt index fa0f003..686e86d 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/screens/plugins/PluginsScreen.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/screens/plugins/PluginsScreen.kt @@ -170,7 +170,7 @@ private fun PluginSearch( ) } }, - keyboardOptions = KeyboardOptions(autoCorrect = false, imeAction = ImeAction.Search), + keyboardOptions = KeyboardOptions(autoCorrectEnabled = false, imeAction = ImeAction.Search), keyboardActions = KeyboardActions { focusManager.clearFocus() }, modifier = modifier, ) diff --git a/app/src/main/kotlin/com/aliucord/manager/ui/util/paddings/ExcludePaddingValues.kt b/app/src/main/kotlin/com/aliucord/manager/ui/util/paddings/ExcludePaddingValues.kt index 3c0bd7d..a458d2b 100644 --- a/app/src/main/kotlin/com/aliucord/manager/ui/util/paddings/ExcludePaddingValues.kt +++ b/app/src/main/kotlin/com/aliucord/manager/ui/util/paddings/ExcludePaddingValues.kt @@ -15,7 +15,7 @@ fun PaddingValues.exclude(sides: PaddingValuesSides): PaddingValues = ExcludePaddingValues(this, sides) @Stable -@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") +@Suppress("INVISIBLE_REFERENCE") private class ExcludePaddingValues( private val values: PaddingValues, private val excludeSides: PaddingValuesSides, diff --git a/app/src/main/kotlin/com/aliucord/manager/util/Context.kt b/app/src/main/kotlin/com/aliucord/manager/util/Context.kt index b2e3013..3b6ed70 100644 --- a/app/src/main/kotlin/com/aliucord/manager/util/Context.kt +++ b/app/src/main/kotlin/com/aliucord/manager/util/Context.kt @@ -50,7 +50,7 @@ fun Context.showToast(@StringRes text: Int, vararg args: Any, length: Int = Toas /** * @return (versionName, versionCode) */ -fun Context.getPackageVersion(pkg: String): Pair { +fun Context.getPackageVersion(pkg: String): Pair { @Suppress("DEPRECATION") return packageManager.getPackageInfo(pkg, 0) .let { it.versionName to it.versionCode } diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 5d4a7ea..b855ebe 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -4,5 +4,9 @@ diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 703630c..b6b29be 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,34 +1,33 @@ [versions] -accompanist = "0.32.0" -agp = "8.2.2" -androidx-activity = "1.8.2" -androidx-core = "1.12.0" +accompanist = "0.37.0" +agp = "8.7.3" # 8.8 breaks proguard +androidx-activity = "1.9.3" +androidx-core = "1.15.0" androidx-splashscreen = "1.0.1" -androidx-lifecycle = "2.7.0" -apksig = "7.4.2" +androidx-lifecycle = "2.8.7" +apksig = "8.8.0" axml = "1.0.1" binary-resources = "2.0.0" bouncycastle = "1.70" -coil = "2.5.0" -compose = "1.5.4" -compose-compiler = "1.5.8" -compose-tracing = "1.0.0-beta01" -compose-material3 = "1.2.0-rc01" +coil = "3.0.4" +compose = "1.7.6" +compose-tracing = "1.7.6" +compose-material3 = "1.3.1" #diff = "4.12" -koin = "3.5.3" -kotlin = "1.9.22" -kotlinx-immutable = "0.3.7" -kotlinx-serialization = "1.5.0" -ktor = "2.3.7" -microg = "0.3.2.240913" -smali = "3.0.7" -voyager = "1.0.0" +koin = "4.0.1" +kotlin = "2.1.0" +kotlinx-immutable = "0.3.8" +kotlinx-serialization = "1.8.0" +ktor = "3.0.3" +microg = "0.3.6.244735" +smali = "3.0.9" +voyager = "1.0.1" zip = "2.1.1" [libraries] # Accompanist accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" } -accompanist-systemUiController = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } +accompanist-systemUiController = { module = "com.google.accompanist:accompanist-systemuicontroller", version = "0.36.0" } # AndroidX androidx-activity = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" } @@ -37,6 +36,10 @@ androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } androidx-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidx-splashscreen" } +# Coil (image library) +coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } +coil-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp", version.ref = "coil" } + # Compose compose-runtime = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } compose-foundation = { module = "androidx.compose.foundation:foundation", version.ref = "compose" } @@ -74,7 +77,6 @@ apksig = { module = "com.android.tools.build:apksig", version.ref = "apksig" } axml = { module = "com.aliucord:axml", version.ref = "axml" } binaryResources = { module = "com.aliucord:binary-resources", version.ref = "binary-resources" } bouncycastle = { module = "org.bouncycastle:bcpkix-jdk15on", version.ref = "bouncycastle" } -coil = { module = "io.coil-kt:coil-compose", version.ref = "coil" } #diff = { module = "io.github.java-diff-utils:java-diff-utils", version.ref = "diff" } diff = "com.github.Aliucord:java-diff-utils:a0002d1d40" # TODO: remove when https://github.com/java-diff-utils/java-diff-utils/pull/198 is merged microg = { module = "org.microg.gms:play-services-safetynet", version.ref = "microg" } @@ -94,6 +96,10 @@ androidx = [ "androidx-lifecycle-process", "androidx-splashscreen", ] +coil = [ + "coil-compose", + "coil-okhttp", +] compose = [ "compose-runtime", "compose-ui", @@ -120,6 +126,7 @@ voyager = [ [plugins] android-application = { id = "com.android.application", version.ref = "agp" } +compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd49..a4b76b9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1af9e09..cea7a79 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a4..f3b75f3 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -43,11 +45,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail