forked from geode-sdk/android-launcher
figure out how to update (almost) everything
This commit is contained in:
15 files changed
+62
-83
No files matched your search
+16
-18
@@ -1,5 +1,3 @@
|
||||
val composeBOM: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
extraWarnings.set(true)
|
||||
@@ -13,7 +11,7 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = 36
|
||||
compileSdk = 37
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.geode.launcher"
|
||||
@@ -80,8 +78,8 @@ android {
|
||||
// enables a polyfill for java Instant on api levels < 26 (used for updater)
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
buildFeatures {
|
||||
compose = true
|
||||
@@ -103,28 +101,28 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation (platform("androidx.compose:compose-bom:$composeBOM"))
|
||||
implementation ("androidx.core:core-ktx:1.18.0")
|
||||
implementation (platform("androidx.compose:compose-bom:2026.08.00"))
|
||||
implementation ("androidx.core:core-ktx:1.19.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.10.0")
|
||||
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.10.0")
|
||||
implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.11.0")
|
||||
implementation ("androidx.lifecycle:lifecycle-viewmodel-compose:2.11.0")
|
||||
implementation ("androidx.activity:activity-compose:1.13.0")
|
||||
implementation ("androidx.activity:activity-ktx:1.13.0")
|
||||
implementation ("androidx.appcompat:appcompat:1.7.1")
|
||||
implementation ("androidx.appcompat:appcompat:1.8.0")
|
||||
implementation ("androidx.documentfile:documentfile:1.1.0")
|
||||
|
||||
implementation ("com.squareup.okio:okio:3.17.0")
|
||||
implementation ("com.squareup.okhttp3:okhttp:5.3.2")
|
||||
implementation ("com.squareup.okhttp3:okhttp-coroutines:5.3.2")
|
||||
implementation ("com.squareup.okio:okio:3.18.2")
|
||||
implementation ("com.squareup.okhttp3:okhttp:5.5.0")
|
||||
implementation ("com.squareup.okhttp3:okhttp-coroutines:5.5.0")
|
||||
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.10.0")
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.10.0")
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1")
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.11.0")
|
||||
implementation ("org.jetbrains.kotlinx:kotlinx-datetime:0.8.0")
|
||||
|
||||
implementation ("com.mikepenz:multiplatform-markdown-renderer-android:0.39.2")
|
||||
implementation ("com.mikepenz:multiplatform-markdown-renderer-m3:0.39.2")
|
||||
implementation ("com.mikepenz:multiplatform-markdown-renderer-android:0.45.0")
|
||||
implementation ("com.mikepenz:multiplatform-markdown-renderer-m3:0.45.0")
|
||||
implementation ("androidx.browser:browser:1.10.0")
|
||||
debugImplementation ("androidx.compose.ui:ui-tooling")
|
||||
coreLibraryDesugaring ("com.android.tools:desugar_jdk_libs:2.1.5")
|
||||
|
||||
@@ -256,7 +256,7 @@ fun mapLaunchStatusToInfo(state: LaunchViewModel.LaunchUIState, inSafeMode: Bool
|
||||
)
|
||||
}
|
||||
is LaunchViewModel.LaunchUIState.Cancelled -> {
|
||||
return mapCancelReasonToInfo(state.reason)
|
||||
mapCancelReasonToInfo(state.reason)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.geode.launcher.utils.GeodeUtils
|
||||
import com.geode.launcher.utils.PreferenceUtils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
|
||||
@Composable
|
||||
@@ -142,7 +143,7 @@ fun onSettings(context: Context) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LongPressButton(onClick: () -> Unit, onLongPress: () -> Unit, enabled: Boolean = true, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit) {
|
||||
fun LongPressButton(onClick: () -> Unit, onLongPress: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, content: @Composable RowScope.() -> Unit) {
|
||||
// compose apis don't provide a good way of adding long press to a button
|
||||
var isLongPress by remember { mutableStateOf(false) }
|
||||
|
||||
@@ -154,11 +155,11 @@ fun LongPressButton(onClick: () -> Unit, onLongPress: () -> Unit, enabled: Boole
|
||||
interactionSource.interactions.collectLatest { interaction ->
|
||||
when (interaction) {
|
||||
is PressInteraction.Press -> {
|
||||
delay(viewConfiguration.longPressTimeoutMillis)
|
||||
delay(viewConfiguration.longPressTimeoutMillis.milliseconds)
|
||||
|
||||
// perform a second delay to make the action more obvious
|
||||
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
delay(viewConfiguration.longPressTimeoutMillis)
|
||||
delay(viewConfiguration.longPressTimeoutMillis.milliseconds)
|
||||
|
||||
haptics.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ import com.geode.launcher.utils.GamePackageUtils
|
||||
import com.geode.launcher.utils.GeodeUtils
|
||||
import com.geode.launcher.utils.PreferenceUtils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
enum class LaunchNotificationType {
|
||||
GEODE_UPDATED, LAUNCHER_UPDATE_AVAILABLE, UPDATE_FAILED, UNSUPPORTED_VERSION, FAILED_LOAD;
|
||||
@@ -87,7 +89,7 @@ fun NotificationCardFromType(type: LaunchNotificationType) {
|
||||
}
|
||||
|
||||
AnimatedNotificationCard(
|
||||
displayLength = 5000L,
|
||||
displayLength = 5.seconds,
|
||||
onClick = {
|
||||
showInfoDialog = true
|
||||
}
|
||||
@@ -140,15 +142,15 @@ fun LaunchNotification(cards: List<LaunchNotificationType>) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AnimatedNotificationCard(modifier: Modifier = Modifier, visibilityDelay: Long = 0L, displayLength: Long = 3000L, onClick: (() -> Unit)? = null, contents: @Composable () -> Unit) {
|
||||
fun AnimatedNotificationCard(modifier: Modifier = Modifier, visibilityDelay: Duration = Duration.ZERO, displayLength: Duration = 3.seconds, onClick: (() -> Unit)? = null, contents: @Composable () -> Unit) {
|
||||
val state = remember {
|
||||
MutableTransitionState(false).apply {
|
||||
targetState = visibilityDelay <= 0
|
||||
targetState = visibilityDelay <= Duration.ZERO
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(true) {
|
||||
if (visibilityDelay > 0) {
|
||||
if (visibilityDelay > Duration.ZERO) {
|
||||
delay(visibilityDelay)
|
||||
state.targetState = true
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
||||
@@ -25,7 +25,6 @@ import okio.sink
|
||||
import okio.source
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InterruptedIOException
|
||||
import kotlin.math.max
|
||||
import kotlin.time.Clock
|
||||
|
||||
@@ -8,6 +8,7 @@ import android.os.Environment
|
||||
import android.provider.DocumentsContract
|
||||
import android.provider.MediaStore
|
||||
import java.io.File
|
||||
import androidx.core.net.toUri
|
||||
|
||||
class FileUtils {
|
||||
// copied from https://stackoverflow.com/questions/17546101/get-real-path-for-uri-android
|
||||
@@ -86,7 +87,7 @@ class FileUtils {
|
||||
val file = File(id)
|
||||
if (file.exists()) return id
|
||||
}
|
||||
val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
|
||||
val contentUri = ContentUris.withAppendedId("content://downloads/public_downloads".toUri(), java.lang.Long.valueOf(id))
|
||||
return getDataColumn(context, contentUri, null, null)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import androidx.core.net.toUri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import com.geode.launcher.BuildConfig
|
||||
import com.geode.launcher.R
|
||||
import com.geode.launcher.UserDirectoryProvider
|
||||
import com.geode.launcher.activityresult.GeodeOpenFileActivityResult
|
||||
import com.geode.launcher.activityresult.GeodeOpenFilesActivityResult
|
||||
import com.geode.launcher.activityresult.GeodeSaveFileActivityResult
|
||||
@@ -430,7 +429,7 @@ object GeodeUtils {
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||
)
|
||||
|
||||
return permissions.all {
|
||||
permissions.all {
|
||||
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,6 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.geode.launcher.R
|
||||
import kotlinx.datetime.Month
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.todayIn
|
||||
import kotlin.time.Clock
|
||||
|
||||
// https://gist.github.com/tkuenneth/ddf598663f041dc79960cda503d14448?permalink_comment_id=4660486#gistcomment-4660486
|
||||
@Composable
|
||||
|
||||
@@ -6,17 +6,19 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
const val MS_TO_SEC = 1000L
|
||||
|
||||
@Composable
|
||||
fun useCountdownTimer(
|
||||
lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
|
||||
time: Long,
|
||||
time: Duration,
|
||||
onCountdownFinish: () -> Unit
|
||||
): Long {
|
||||
var millisUntilFinished by remember {
|
||||
mutableLongStateOf(time)
|
||||
mutableStateOf(time)
|
||||
}
|
||||
|
||||
var shouldBeCounting by remember {
|
||||
@@ -28,9 +30,9 @@ fun useCountdownTimer(
|
||||
return@LaunchedEffect
|
||||
}
|
||||
|
||||
if (millisUntilFinished > 0) {
|
||||
delay(MS_TO_SEC)
|
||||
millisUntilFinished -= MS_TO_SEC
|
||||
if (millisUntilFinished > Duration.ZERO) {
|
||||
delay(1.seconds)
|
||||
millisUntilFinished -= 1.seconds
|
||||
} else {
|
||||
onCountdownFinish()
|
||||
}
|
||||
@@ -58,5 +60,5 @@ fun useCountdownTimer(
|
||||
}
|
||||
}
|
||||
|
||||
return millisUntilFinished / MS_TO_SEC
|
||||
return millisUntilFinished.inWholeSeconds
|
||||
}
|
||||
+4
-8
@@ -1,13 +1,9 @@
|
||||
buildscript {
|
||||
val composeBOM by extra("2026.03.01")
|
||||
}
|
||||
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
id("com.android.application") version "9.1.0" apply false
|
||||
id("com.android.library") version "9.1.0" apply false
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version "2.3.20" apply false
|
||||
id("org.jetbrains.kotlin.plugin.compose") version "2.3.20" apply false
|
||||
id("com.android.application") version "9.4.0" apply false
|
||||
id("com.android.library") version "9.4.0" apply false
|
||||
id("org.jetbrains.kotlin.plugin.serialization") version "2.4.10" apply false
|
||||
id("org.jetbrains.kotlin.plugin.compose") version "2.4.10" apply false
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+3
-2
@@ -1,8 +1,9 @@
|
||||
#Sun Apr 05 23:29:16 MST 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.7.1-bin.zip
|
||||
networkTimeout=10000
|
||||
retries=0
|
||||
retryBackOffMs=500
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
# gradlew start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
@@ -29,7 +29,7 @@
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
# ksh gradlew
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/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/.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,8 +210,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
Vendored
+12
-24
@@ -19,12 +19,12 @@
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem gradlew startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
@rem Set local scope for the variables, and ensure extensions are enabled
|
||||
setlocal EnableExtensions
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@@ -51,7 +51,7 @@ 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
|
||||
"%COMSPEC%" /c exit 1
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
@@ -65,30 +65,18 @@ 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
|
||||
"%COMSPEC%" /c exit 1
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
@rem Execute gradlew
|
||||
@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
|
||||
@rem which allows us to clear the local environment before executing the java command
|
||||
endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
:exitWithErrorLevel
|
||||
@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
|
||||
"%COMSPEC%" /c exit %ERRORLEVEL%
|
||||
Reference in new issue
Block a user