Compare commits

..
15 Commits
Author SHA1 Message Date
Lncvrt f59492ca8e XPSified 2025-08-30 20:41:06 -07:00
Chloe 352ff63ab0 also send timestamp for back 2025-05-03 16:33:19 -07:00
Chloe 91fc804dee bump version 2025-05-03 16:24:55 -07:00
Chloe 87808b56b3 remove premature bug fix 2025-05-03 16:22:21 -07:00
Chloe 2c2884c3b8 use indeterminate state instead of ellipses 2025-05-03 16:14:12 -07:00
Chloe 74e91e7dc1 document some unlisted methods 2025-05-03 14:29:40 -07:00
Chloe e3ffbf311e try it 2025-05-03 14:13:39 -07:00
Chloe 5ad77bca57 i forgot i never actually committed that 2025-05-03 03:27:25 -07:00
Chloe 3be0127e04 unfortunate 2025-05-03 03:24:39 -07:00
Chloe 458c837aba add index release api opt in 2025-05-03 03:16:29 -07:00
Chloe 67ca7707d8 support predictive back gestures 2025-04-24 11:59:31 -07:00
Chloe 776a4fa468 obligatory update commit 2025-04-24 11:00:12 -07:00
Chloe 9528eef313 bump tulip 2025-04-23 23:56:55 -07:00
Chloe 9827fe36c1 add screen insets utils 2025-04-23 23:56:54 -07:00
Oleksandr Nemesh ce44270b7a add webview util (#37) 2025-04-22 13:01:53 -07:00
49 changed files with 156 additions and 54 deletions

No files matched your search

+18 -16
View File
@@ -14,14 +14,14 @@ plugins {
}
android {
compileSdk = 35
compileSdk = 36
defaultConfig {
applicationId = "com.geode.launcherXps"
minSdk = 26
minSdk = 23
targetSdk = 35
versionCode = 1
versionName = "1.0.0"
versionCode = 22
versionName = "1.0.1"
vectorDrawables {
useSupportLibrary = true
@@ -30,7 +30,7 @@ android {
@Suppress("UnstableApiUsage")
externalNativeBuild {
cmake {
arguments("-DUSE_TULIPHOOK:BOOL=OFF", "-DANDROID_STL=c++_shared")
arguments("-DUSE_TULIPHOOK:BOOL=OFF", "-DANDROID_STL=c++_shared", "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES:BOOL=OFF")
}
}
@@ -82,32 +82,34 @@ android {
}
externalNativeBuild {
cmake {
version = "3.25.0+"
path = file("src/main/cpp/CMakeLists.txt")
}
}
namespace = "com.geode.launcher"
ndkVersion = "27.2.12479018"
ndkVersion = "28.1.13356709"
}
dependencies {
implementation (platform("androidx.compose:compose-bom:$composeBOM"))
implementation ("androidx.core:core-ktx:1.15.0")
implementation ("androidx.core:core-ktx:1.16.0")
implementation ("androidx.compose.ui:ui")
implementation ("androidx.compose.material3:material3")
implementation ("androidx.compose.ui:ui-tooling-preview")
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7")
implementation ("androidx.activity:activity-compose:1.10.0")
implementation ("androidx.activity:activity-ktx:1.10.0")
implementation ("androidx.activity:activity-compose:1.10.1")
implementation ("androidx.activity:activity-ktx:1.10.1")
implementation ("androidx.appcompat:appcompat:1.7.0")
implementation ("androidx.documentfile:documentfile:1.0.1")
implementation ("com.squareup.okio:okio:3.10.2")
implementation ("com.squareup.okio:okio:3.11.0")
implementation ("com.squareup.okhttp3:okhttp:4.12.0")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.8.0")
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1")
implementation ("com.mikepenz:multiplatform-markdown-renderer-android:0.30.0")
implementation ("com.mikepenz:multiplatform-markdown-renderer-m3:0.30.0")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.8.1")
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.6.2")
implementation ("com.mikepenz:multiplatform-markdown-renderer-android:0.33.0")
implementation ("com.mikepenz:multiplatform-markdown-renderer-m3:0.33.0")
implementation ("androidx.browser:browser:1.8.0")
debugImplementation ("androidx.compose.ui:ui-tooling")
coreLibraryDesugaring ("com.android.tools:desugar_jdk_libs:2.1.4")
coreLibraryDesugaring ("com.android.tools:desugar_jdk_libs:2.1.5")
}
+2 -1
View File
@@ -39,8 +39,9 @@
android:label="@string/app_name"
android:hasFragileUserData="true"
android:requestLegacyExternalStorage="true"
android:enableOnBackInvokedCallback="true"
android:theme="@style/Theme.GeodeLauncher"
tools:targetApi="31">
tools:targetApi="35">
<activity
android:name=".AltMainActivity"
android:exported="false"
+3 -2
View File
@@ -13,7 +13,7 @@ option(USE_TULIPHOOK "enables choice of hooking library" OFF)
if (USE_TULIPHOOK)
FetchContent_Declare(TulipHook
GIT_REPOSITORY https://github.com/geode-sdk/TulipHook.git
GIT_TAG 0021301fcea265416fa8eb5372694931c1d410cb
GIT_TAG 9aa1f95091ebac18c657d57b755f59d00fe6f1f8
)
set(TULIP_LINK_SOURCE ON CACHE INTERNAL "")
@@ -24,8 +24,9 @@ if (USE_TULIPHOOK)
target_link_libraries(launcherfix PRIVATE TulipHook TulipHookInclude)
else()
FetchContent_Declare(dobby
# this is the last version that builds on android at all
GIT_REPOSITORY https://github.com/jmpews/Dobby
GIT_TAG 6a80a61ea062424d1595613058a174c64454fa57
GIT_TAG 0932d69c320e786672361ab53825ba8f4245e9d3
)
FetchContent_GetProperties(dobby)
+1 -1
View File
@@ -109,7 +109,7 @@ bool patch_symbol(std::uint32_t* hash_table, char* str_table, ElfW(Sym)* sym_tab
// we found it! now go rename the symbol
#ifdef USE_TULIPHOOK
auto res = tulip::hook::writeMemory(sym_name, new_symbol.data(), new_symbol.size());
auto res = tulip::hook::writeMemory(sym_name, SYMBOL_PATCH_VALUE.data(), SYMBOL_PATCH_VALUE.size());
if (!res) {
__android_log_print(ANDROID_LOG_WARN, "GeodeLauncher-fix", "failed to patch symbol: %s", res.unwrapErr().c_str());
return false;
@@ -14,6 +14,7 @@ import android.util.Log
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.FrameLayout
import android.window.OnBackInvokedDispatcher
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.ui.platform.ComposeView
@@ -121,6 +122,13 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
onBackInvokedDispatcher.registerOnBackInvokedCallback(OnBackInvokedDispatcher.PRIORITY_DEFAULT) {
mGLSurfaceView?.sendKeyBack()
}
mGLSurfaceView?.manualBackEvents = true
}
}
private fun createVersionFile() {
@@ -472,6 +480,9 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
if (displayMode == DisplayMode.FULLSCREEN && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
GeodeUtils.handleSafeArea = true
} else {
GeodeUtils.handleSafeArea = false
}
hideSystemUi()
@@ -58,9 +58,9 @@ import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils
import com.mikepenz.markdown.compose.LocalBulletListHandler
import com.mikepenz.markdown.m3.Markdown
import com.mikepenz.markdown.m3.markdownColor
import com.mikepenz.markdown.m3.markdownTypography
import kotlinx.datetime.toJavaInstant
import org.intellij.markdown.flavours.gfm.GFMFlavourDescriptor
import java.io.File
import java.net.ConnectException
import java.net.UnknownHostException
@@ -176,7 +176,7 @@ fun LauncherUpdateInformation(onDismiss: () -> Unit) {
IconButton(onClick = { uriHandler.openUri(nextRelease.release.htmlUrl) }) {
Icon(
painterResource(R.drawable.xps_icon),
painterResource(R.drawable.icon_link),
stringResource(R.string.launcher_update_external_link)
)
}
@@ -191,17 +191,17 @@ fun LauncherUpdateInformation(onDismiss: () -> Unit) {
style = Typography.titleLarge
)
CompositionLocalProvider(LocalBulletListHandler provides { _, _, _ -> "•  " }) {
// every new release of the markdown library adds another arg to it
CompositionLocalProvider(LocalBulletListHandler provides { _, _, _, _, _ -> "•  " }) {
Markdown(
content = nextRelease.release.body.replace("\r", ""),
colors = markdownColor(
linkText = MaterialTheme.colorScheme.primary
),
typography = markdownTypography(
link = MaterialTheme.typography.bodyLarge.copy(
textDecoration = TextDecoration.Underline
)
textDecoration = TextDecoration.Underline,
color = MaterialTheme.colorScheme.primary,
),
),
flavour = GFMFlavourDescriptor(),
)
}
}
@@ -370,10 +370,13 @@ fun UpdateCard(releaseViewModel: ReleaseViewModel, modifier: Modifier = Modifier
}
UpdateProgressIndicator(
stringResource(
if (outOf != null) stringResource(
R.string.release_fetch_downloading,
downloaded,
outOf ?: "…"
outOf
) else stringResource(
R.string.release_fetch_downloading_indeterminate,
downloaded,
),
modifier = modifier,
releaseViewModel = releaseViewModel,
@@ -146,6 +146,11 @@ fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) {
}
OptionsGroup(title = stringResource(R.string.preference_category_updater)) {
SettingsCard(
title = stringResource(R.string.preference_use_index_update_api),
preferenceKey = PreferenceUtils.Key.USE_INDEX_API
)
SettingsSelectCard(
title = stringResource(R.string.preference_release_channel_tag_name),
dialogTitle = stringResource(R.string.preference_release_channel_select),
@@ -120,6 +120,17 @@ class ReleaseManager private constructor(
}
val gameVersion = GamePackageUtils.getGameVersionCode(applicationContext.packageManager)
val preferences = PreferenceUtils.get(applicationContext)
if (preferences.getBoolean(PreferenceUtils.Key.USE_INDEX_API)) {
val targetTag = preferences.getInt(PreferenceUtils.Key.RELEASE_CHANNEL_TAG)
return when (targetTag) {
2 -> releaseRepository.getReleaseByTag("nightly")
1 -> releaseRepository.getLatestIndexRelease(gameVersion, true)
else -> releaseRepository.getLatestIndexRelease(gameVersion, false)
}
} else {
val targetTag = getBestReleaseForGameVersion(gameVersion) ?: return null
return when (targetTag) {
@@ -128,6 +139,7 @@ class ReleaseManager private constructor(
else -> releaseRepository.getReleaseByTag(targetTag)
}
}
}
private suspend fun downloadLauncherUpdate(release: Downloadable) {
val download = release.getDownload() ?: return
@@ -165,10 +165,10 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
}
@OptIn(ExperimentalSerializationApi::class)
suspend fun getLatestIndexRelease(gd: String, prerelease: Boolean = false): DownloadableLoaderRelease? {
suspend fun getLatestIndexRelease(gd: Long, prerelease: Boolean = false): DownloadableLoaderRelease? {
val url = "$GEODE_API_BASE/loader/versions/latest".toHttpUrlOrNull()!!
.newBuilder()
.addQueryParameter("gd", gd)
.addQueryParameter("gd", gd.toString())
.addQueryParameter("platform", "android")
.addQueryParameter("prerelease", prerelease.toString())
.build()
@@ -21,7 +21,9 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.Keep
import androidx.appcompat.app.AppCompatActivity
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.documentfile.provider.DocumentFile
import com.geode.launcher.BuildConfig
import com.geode.launcher.R
@@ -37,6 +39,8 @@ import kotlin.system.exitProcess
@Suppress("unused", "KotlinJniMissingFunction")
object GeodeUtils {
private lateinit var activity: WeakReference<AppCompatActivity>
var handleSafeArea: Boolean = false
private lateinit var openFileResultLauncher: ActivityResultLauncher<GeodeOpenFileActivityResult.OpenFileParams>
private lateinit var openDirectoryResultLauncher: ActivityResultLauncher<Uri?>
private lateinit var openFilesResultLauncher: ActivityResultLauncher<GeodeOpenFilesActivityResult.OpenFileParams>
@@ -386,6 +390,9 @@ object GeodeUtils {
return ""
}
/**
* Returns the current version code of the launcher.
*/
@JvmStatic
fun getLauncherVersion(): Int {
return BuildConfig.VERSION_CODE
@@ -457,9 +464,16 @@ object GeodeUtils {
}
// vibration
/**
* If vibration is supported on the device.
*/
@JvmStatic
fun vibrateSupported(): Boolean = getVibrator()?.hasVibrator() == true
/**
* Vibrates for the given amount of time.
*/
@JvmStatic
fun vibrate(ms: Long) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -470,6 +484,10 @@ object GeodeUtils {
}
}
/**
* Vibrates with the given pattern.
* @see android.os.VibrationEffect.createWaveform
*/
@JvmStatic
fun vibratePattern(pattern: LongArray, repeat: Int) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -480,6 +498,19 @@ object GeodeUtils {
}
}
@JvmStatic
fun getScreenInsets(): IntArray? {
if (!handleSafeArea || Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
return null
}
return activity.get()?.run {
val displayCutout = window.decorView.rootWindowInsets?.displayCutout ?: return null
intArrayOf(displayCutout.safeInsetLeft, displayCutout.safeInsetBottom, displayCutout.safeInsetRight, displayCutout.safeInsetTop)
}
}
const val ARGUMENT_SAFE_MODE = "--geode:safe-mode"
private var additionalLaunchArguments = arrayListOf<String>()
@@ -518,6 +549,10 @@ object GeodeUtils {
capabilityListener = WeakReference(listener)
}
/**
* Reports that the game client supports a feature.
* These features typically require callbacks into the game, so ensure that the required methods are registered first.
*/
@JvmStatic
fun reportPlatformCapability(capability: String?): Boolean {
if (capability.isNullOrEmpty()) {
@@ -527,11 +562,24 @@ object GeodeUtils {
return capabilityListener.get()?.onCapabilityAdded(capability) == true
}
@JvmStatic
fun openWebview(url: String) {
val activity = activity.get() ?: return
CustomTabsIntent.Builder()
.setShowTitle(true)
.build()
.launchUrl(activity, url.toUri())
}
external fun nativeKeyUp(keyCode: Int, modifiers: Int)
external fun nativeKeyDown(keyCode: Int, modifiers: Int, isRepeating: Boolean)
external fun nativeActionScroll(scrollX: Float, scrollY: Float)
external fun resizeSurface(width: Int, height: Int)
// represents the timestamp of the next input callback, in nanoseconds (most events don't send it, but it's there)
/**
* Gives the timestamp of the next input callback, in nanoseconds.
* Enable this by sending the "timestamp_inputs" platform capability.
* @see reportPlatformCapability
*/
external fun setNextInputTimestamp(timestamp: Long)
}
@@ -147,13 +147,15 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
CUSTOM_ASPECT_RATIO,
SCREEN_ZOOM,
SCREEN_ZOOM_FIT,
LIMIT_FRAME_RATE
LIMIT_FRAME_RATE,
USE_INDEX_API,
}
private fun defaultValueForBooleanKey(key: Key): Boolean {
return when (key) {
Key.UPDATE_AUTOMATICALLY, Key.FORCE_HRR -> true
Key.DEVELOPER_MODE -> BuildConfig.DEBUG
Key.USE_INDEX_API -> true
else -> false
}
}
@@ -195,6 +197,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
Key.SCREEN_ZOOM -> "PreferenceScreenZoom"
Key.SCREEN_ZOOM_FIT -> "PreferenceScreenZoomFit"
Key.LIMIT_FRAME_RATE -> "PreferenceLimitFrameRate"
Key.USE_INDEX_API -> "PreferenceUseIndexApi"
}
}
@@ -55,6 +55,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
}
var sendTimestampEvents = false
var manualBackEvents = false
var cocos2dxEditText: Cocos2dxEditText? = null
set(value) {
@@ -259,6 +260,26 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
}
}
fun sendKeyBack() {
if (BaseRobTopActivity.blockBackButton) {
return
}
if (useKeyboardEvents) {
queueEvent {
cocos2dxRenderer.handleKeyDown(KeyEvent.KEYCODE_BACK)
}
} else {
val currentTime = System.nanoTime()
queueEvent {
if (sendTimestampEvents)
GeodeUtils.setNextInputTimestamp(currentTime)
GeodeUtils.nativeKeyDown(KeyEvent.KEYCODE_BACK, 0, false)
}
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (!useKeyboardEvents) {
return legacyKeyDown(keyCode, event)
-5
View File
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
</adaptive-icon>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

+2
View File
@@ -84,6 +84,7 @@
<string name="release_fetch_in_progress">Checking for new releases…</string>
<string name="release_fetch_success">Geode updated!</string>
<string name="release_fetch_downloading">Downloading update… (%1$s/%2$s)</string>
<string name="release_fetch_downloading_indeterminate">Downloading update… (%1$s)</string>
<string name="release_fetch_cancelling">Cancelling update…</string>
<string name="release_fetch_no_internet">No internet found.</string>
<string name="release_fetch_cancelled">Update cancelled.</string>
@@ -254,4 +255,5 @@
<string name="preference_override_exceptions_name">Custom exceptions fix symbols</string>
<string name="preference_override_exceptions_description">Uses exception_symbols.txt to patch</string>
<string name="preference_use_index_update_api">Use index release API</string>
</resources>
+2 -1
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.NoActionBar.Fullscreen" parent="@style/Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowNoTitle">true</item>
@@ -7,6 +7,7 @@
<item name="android:windowFullscreen">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:drawable/screen_background_dark</item>
<item name="android:windowOptOutEdgeToEdgeEnforcement" tools:targetApi="35">true</item>
</style>
<style name="Theme.GeodeLauncher" parent="android:Theme.Material.Light.NoActionBar" />
+6 -6
View File
@@ -1,14 +1,14 @@
buildscript {
val composeBOM by extra("2025.01.00")
val composeBOM by extra("2025.04.01")
}
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id("com.android.application") version "8.7.3" apply false
id("com.android.library") version "8.7.3" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.0" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
id("com.android.application") version "8.9.2" apply false
id("com.android.library") version "8.9.2" apply false
id("org.jetbrains.kotlin.android") version "2.1.20" apply false
id("org.jetbrains.kotlin.plugin.serialization") version "2.1.20" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.1.20" apply false
}
tasks.register<Delete>("clean") {
+2 -1
View File
@@ -1,6 +1,7 @@
#Thu Apr 24 10:54:01 MST 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME