mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 16:32:39 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dd122631c |
No files matched your search
@@ -24,8 +24,10 @@ import androidx.core.view.WindowCompat
|
|||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
import androidx.core.view.WindowInsetsControllerCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.customRobTop.BaseRobTopActivity
|
import com.customRobTop.BaseRobTopActivity
|
||||||
import com.customRobTop.JniToCpp
|
import com.customRobTop.JniToCpp
|
||||||
|
import com.geode.launcher.main.FullScreenLoadingIndicator
|
||||||
import com.geode.launcher.main.LaunchNotification
|
import com.geode.launcher.main.LaunchNotification
|
||||||
import com.geode.launcher.main.determineDisplayedCards
|
import com.geode.launcher.main.determineDisplayedCards
|
||||||
import com.geode.launcher.utils.Constants
|
import com.geode.launcher.utils.Constants
|
||||||
@@ -35,13 +37,14 @@ import com.geode.launcher.utils.GamePackageUtils
|
|||||||
import com.geode.launcher.utils.GeodeUtils
|
import com.geode.launcher.utils.GeodeUtils
|
||||||
import com.geode.launcher.utils.LaunchUtils
|
import com.geode.launcher.utils.LaunchUtils
|
||||||
import com.geode.launcher.utils.PreferenceUtils
|
import com.geode.launcher.utils.PreferenceUtils
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.cocos2dx.lib.Cocos2dxGLSurfaceView
|
import org.cocos2dx.lib.Cocos2dxGLSurfaceView
|
||||||
import org.cocos2dx.lib.Cocos2dxHelper
|
import org.cocos2dx.lib.Cocos2dxHelper
|
||||||
import org.cocos2dx.lib.Cocos2dxRenderer
|
import org.cocos2dx.lib.Cocos2dxRenderer
|
||||||
import org.fmod.FMOD
|
import org.fmod.FMOD
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.io.FileOutputStream
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.microedition.khronos.egl.EGL10
|
import javax.microedition.khronos.egl.EGL10
|
||||||
import javax.microedition.khronos.egl.EGLConfig
|
import javax.microedition.khronos.egl.EGLConfig
|
||||||
@@ -91,97 +94,88 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
val rootLayout = setupContext()
|
||||||
createVersionFile()
|
val loadingView = ComposeView(this).apply {
|
||||||
tryLoadGame()
|
setContent {
|
||||||
} catch (e: UnsatisfiedLinkError) {
|
FullScreenLoadingIndicator()
|
||||||
Log.e("GeodeLauncher", "Library linkage failure", e)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generates helpful information for use in debugging library load failures
|
if (rootLayout != null) {
|
||||||
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
rootLayout.addView(loadingView)
|
||||||
val abiMismatch = GamePackageUtils.detectAbiMismatch(this, gdPackageInfo, e)
|
} else {
|
||||||
|
setContentView(loadingView)
|
||||||
|
}
|
||||||
|
|
||||||
val is64bit = LaunchUtils.is64bit
|
lifecycleScope.launch {
|
||||||
val errorMessage = when {
|
val error = preloadGame(rootLayout)
|
||||||
abiMismatch && is64bit -> LaunchUtils.LauncherError.LINKER_NEEDS_32BIT
|
if (error != null) {
|
||||||
abiMismatch -> LaunchUtils.LauncherError.LINKER_NEEDS_64BIT
|
returnToMain(error)
|
||||||
e.message?.contains("__gxx_personality_v0") == true ->
|
|
||||||
LaunchUtils.LauncherError.LINKER_FAILED_STL
|
|
||||||
else -> LaunchUtils.LauncherError.LINKER_FAILED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
returnToMain(errorMessage, e.message, e.stackTraceToString())
|
rootLayout?.removeView(loadingView)
|
||||||
|
|
||||||
return
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("GeodeLauncher", "Uncaught error during game load", e)
|
|
||||||
|
|
||||||
returnToMain(
|
|
||||||
LaunchUtils.LauncherError.GENERIC,
|
|
||||||
e.message ?: "Unknown Exception",
|
|
||||||
e.stackTraceToString()
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun preloadGame(rootLayout: FrameLayout?): LaunchUtils.FullLauncherError? = try {
|
||||||
|
createVersionFile()
|
||||||
|
val loadFailed = tryLoadGame()
|
||||||
|
|
||||||
|
val baseView = createView()
|
||||||
|
|
||||||
|
if (rootLayout != null) {
|
||||||
|
rootLayout.addView(baseView)
|
||||||
|
} else {
|
||||||
|
setContentView(baseView)
|
||||||
|
}
|
||||||
|
|
||||||
|
mGLSurfaceView?.manualBackEvents = true
|
||||||
|
|
||||||
|
setupNotificationView(baseView, loadFailed)
|
||||||
|
|
||||||
|
null
|
||||||
|
} catch (e: UnsatisfiedLinkError) {
|
||||||
|
Log.e("GeodeLauncher", "Library linkage failure", e)
|
||||||
|
|
||||||
|
// generates helpful information for use in debugging library load failures
|
||||||
|
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
|
val abiMismatch = GamePackageUtils.detectAbiMismatch(this, gdPackageInfo, e)
|
||||||
|
|
||||||
|
val is64bit = LaunchUtils.is64bit
|
||||||
|
val errorMessage = when {
|
||||||
|
abiMismatch && is64bit -> LaunchUtils.LauncherError.LINKER_NEEDS_32BIT
|
||||||
|
abiMismatch -> LaunchUtils.LauncherError.LINKER_NEEDS_64BIT
|
||||||
|
e.message?.contains("__gxx_personality_v0") == true ->
|
||||||
|
LaunchUtils.LauncherError.LINKER_FAILED_STL
|
||||||
|
else -> LaunchUtils.LauncherError.LINKER_FAILED
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchUtils.FullLauncherError(
|
||||||
|
errorMessage,
|
||||||
|
e.message ?: "Unknown exception",
|
||||||
|
e.stackTraceToString()
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("GeodeLauncher", "Uncaught error during game load", e)
|
||||||
|
|
||||||
|
LaunchUtils.FullLauncherError(
|
||||||
|
LaunchUtils.LauncherError.GENERIC,
|
||||||
|
e.message ?: "Unknown Exception",
|
||||||
|
e.stackTraceToString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupContext(): FrameLayout? {
|
||||||
|
Cocos2dxHelper.init(this, this)
|
||||||
|
|
||||||
|
GeodeUtils.setContext(this)
|
||||||
|
GeodeUtils.setCapabilityListener(this)
|
||||||
|
|
||||||
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
mGLSurfaceView?.sendKeyBack()
|
mGLSurfaceView?.sendKeyBack()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
mGLSurfaceView?.manualBackEvents = true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createVersionFile() {
|
|
||||||
val versionPath = File(filesDir, "game_version.txt")
|
|
||||||
val gameVersion = GamePackageUtils.getGameVersionCode(packageManager)
|
|
||||||
|
|
||||||
versionPath.writeText("$gameVersion")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun returnToMain(
|
|
||||||
error: LaunchUtils.LauncherError? = null,
|
|
||||||
returnMessage: String? = null,
|
|
||||||
returnExtendedMessage: String? = null
|
|
||||||
) {
|
|
||||||
val launchIntent = Intent(this, MainActivity::class.java).apply {
|
|
||||||
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
|
|
||||||
if (error != null && !returnMessage.isNullOrEmpty()) {
|
|
||||||
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_ERROR, error)
|
|
||||||
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_MESSAGE, returnMessage)
|
|
||||||
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_EXTENDED_MESSAGE, returnExtendedMessage)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
startActivity(launchIntent)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun tryLoadGame() {
|
|
||||||
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
|
||||||
|
|
||||||
setupRedirection(gdPackageInfo)
|
|
||||||
|
|
||||||
Cocos2dxHelper.init(this, this)
|
|
||||||
|
|
||||||
GeodeUtils.setContext(this)
|
|
||||||
GeodeUtils.setCapabilityListener(this)
|
|
||||||
|
|
||||||
tryLoadLibrary(gdPackageInfo, Constants.FMOD_LIB_NAME)
|
|
||||||
tryLoadLibrary(gdPackageInfo, Constants.COCOS_LIB_NAME)
|
|
||||||
|
|
||||||
if (GamePackageUtils.getGameVersionCode(packageManager) >= 39L) {
|
|
||||||
// this fix requires geode v3, which is 2.206+
|
|
||||||
// there is a short period in which 2.206 users will still have geode v2, but whatever. ig
|
|
||||||
LauncherFix.enableExceptionsRenaming()
|
|
||||||
}
|
|
||||||
|
|
||||||
LauncherFix.performPatches()
|
|
||||||
|
|
||||||
loadInternalMods()
|
|
||||||
|
|
||||||
val baseView = createView()
|
|
||||||
|
|
||||||
if (!GeodeUtils.handleSafeArea && Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) {
|
if (!GeodeUtils.handleSafeArea && Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA) {
|
||||||
val frameLayoutParams = ViewGroup.LayoutParams(
|
val frameLayoutParams = ViewGroup.LayoutParams(
|
||||||
@@ -204,15 +198,61 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
WindowInsets.CONSUMED
|
WindowInsets.CONSUMED
|
||||||
}
|
}
|
||||||
|
|
||||||
frameLayout.addView(baseView)
|
|
||||||
setContentView(frameLayout)
|
setContentView(frameLayout)
|
||||||
} else {
|
return frameLayout
|
||||||
setContentView(baseView)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun createVersionFile() = runCatching {
|
||||||
|
val gameVersion = GamePackageUtils.getGameVersionCode(packageManager)
|
||||||
|
|
||||||
|
val versionPath = File(filesDir, "game_version.txt")
|
||||||
|
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
if (versionPath.exists()) {
|
||||||
|
versionPath.delete()
|
||||||
|
}
|
||||||
|
|
||||||
|
versionPath.writeText("$gameVersion")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun returnToMain(message: LaunchUtils.FullLauncherError? = null, ) {
|
||||||
|
val launchIntent = Intent(this, MainActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
|
||||||
|
if (message != null) {
|
||||||
|
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_ERROR, message.error)
|
||||||
|
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_MESSAGE, message.returnMessage)
|
||||||
|
putExtra(LaunchUtils.LAUNCHER_KEY_RETURN_EXTENDED_MESSAGE, message.extendedMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startActivity(launchIntent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun tryLoadGame(): Boolean {
|
||||||
|
val gdPackageInfo = packageManager.getPackageInfo(Constants.PACKAGE_NAME, 0)
|
||||||
|
setupRedirection(gdPackageInfo)
|
||||||
|
|
||||||
|
tryLoadLibrary(gdPackageInfo, Constants.FMOD_LIB_NAME)
|
||||||
|
tryLoadLibrary(gdPackageInfo, Constants.COCOS_LIB_NAME)
|
||||||
|
|
||||||
|
if (GamePackageUtils.getGameVersionCode(packageManager) >= 39L) {
|
||||||
|
// this fix requires geode v3, which is 2.206+
|
||||||
|
// there is a short period in which 2.206 users will still have geode v2, but whatever. ig
|
||||||
|
LauncherFix.enableExceptionsRenaming()
|
||||||
|
}
|
||||||
|
|
||||||
|
LauncherFix.performPatches()
|
||||||
|
|
||||||
|
loadInternalMods()
|
||||||
|
|
||||||
setupPostLibraryLoad(gdPackageInfo)
|
setupPostLibraryLoad(gdPackageInfo)
|
||||||
|
|
||||||
val geodeFailed = try {
|
return try {
|
||||||
loadGeodeLibrary()
|
loadGeodeLibrary()
|
||||||
false
|
false
|
||||||
} catch (e: UnsatisfiedLinkError) {
|
} catch (e: UnsatisfiedLinkError) {
|
||||||
@@ -222,8 +262,6 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
handleGeodeException(e)
|
handleGeodeException(e)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
setupNotificationView(baseView, geodeFailed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupNotificationView(baseView: FrameLayout, geodeFailed: Boolean) {
|
private fun setupNotificationView(baseView: FrameLayout, geodeFailed: Boolean) {
|
||||||
@@ -283,7 +321,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
private fun tryLoadLibrary(packageInfo: PackageInfo, libraryName: String) {
|
private suspend fun tryLoadLibrary(packageInfo: PackageInfo, libraryName: String) {
|
||||||
val nativeDir = getNativeLibraryDirectory(packageInfo.applicationInfo!!)
|
val nativeDir = getNativeLibraryDirectory(packageInfo.applicationInfo!!)
|
||||||
val libraryPath = if (nativeDir.endsWith('/')) "${nativeDir}lib$libraryName.so" else "$nativeDir/lib$libraryName.so"
|
val libraryPath = if (nativeDir.endsWith('/')) "${nativeDir}lib$libraryName.so" else "$nativeDir/lib$libraryName.so"
|
||||||
|
|
||||||
@@ -302,7 +340,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
private fun loadLibraryCopy(libraryName: String, libraryPath: String) {
|
private suspend fun loadLibraryCopy(libraryName: String, libraryPath: String) {
|
||||||
if (libraryPath.contains("!/")) {
|
if (libraryPath.contains("!/")) {
|
||||||
// library in apk can't be loaded directly
|
// library in apk can't be loaded directly
|
||||||
loadLibraryFromAssetsCopy(libraryName)
|
loadLibraryFromAssetsCopy(libraryName)
|
||||||
@@ -312,11 +350,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
val library = File(libraryPath)
|
val library = File(libraryPath)
|
||||||
val libraryCopy = File(cacheDir, "lib$libraryName.so")
|
val libraryCopy = File(cacheDir, "lib$libraryName.so")
|
||||||
|
|
||||||
libraryCopy.outputStream().use { libraryOutput ->
|
DownloadUtils.copyFile(library, libraryCopy)
|
||||||
library.inputStream().use { inputStream ->
|
|
||||||
DownloadUtils.copyFile(inputStream, libraryOutput)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
System.load(libraryCopy.path)
|
System.load(libraryCopy.path)
|
||||||
|
|
||||||
@@ -324,7 +358,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
private fun loadLibraryFromAssetsCopy(libraryName: String) {
|
private suspend fun loadLibraryFromAssetsCopy(libraryName: String) {
|
||||||
// loads a library loaded in assets
|
// loads a library loaded in assets
|
||||||
// this copies the library to a non-compressed directory
|
// this copies the library to a non-compressed directory
|
||||||
|
|
||||||
@@ -339,9 +373,11 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
// there doesn't seem to be a way to load a library from a file descriptor
|
// there doesn't seem to be a way to load a library from a file descriptor
|
||||||
val libraryCopy = File(cacheDir, "lib$libraryName.so")
|
val libraryCopy = File(cacheDir, "lib$libraryName.so")
|
||||||
|
|
||||||
libraryCopy.outputStream().use { libraryOutput ->
|
withContext(Dispatchers.IO) {
|
||||||
libraryFd.createInputStream().use { inputStream ->
|
libraryCopy.outputStream().use { libraryOutput ->
|
||||||
DownloadUtils.copyFile(inputStream, libraryOutput)
|
libraryFd.createInputStream().use { inputStream ->
|
||||||
|
DownloadUtils.copyFile(inputStream, libraryOutput)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +412,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
@SuppressLint("UnsafeDynamicallyLoadedCode")
|
||||||
private fun loadGeodeLibrary() {
|
private suspend fun loadGeodeLibrary() {
|
||||||
// Load Geode if exists
|
// Load Geode if exists
|
||||||
// bundling the object with the application allows for nicer backtraces
|
// bundling the object with the application allows for nicer backtraces
|
||||||
try {
|
try {
|
||||||
@@ -397,22 +433,23 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
// also i get 20 million permission denied errors
|
// also i get 20 million permission denied errors
|
||||||
val externalGeodePath = LaunchUtils.getInstalledGeodePath(this)!!
|
val externalGeodePath = LaunchUtils.getInstalledGeodePath(this)!!
|
||||||
|
|
||||||
val copiedPath = File(filesDir.path, "copied")
|
val copiedPath = File(filesDir, "copied")
|
||||||
if (copiedPath.exists()) {
|
if (copiedPath.exists()) {
|
||||||
copiedPath.deleteRecursively()
|
copiedPath.deleteRecursively()
|
||||||
}
|
}
|
||||||
copiedPath.mkdir()
|
copiedPath.mkdir()
|
||||||
|
|
||||||
val copiedGeodePath = File(copiedPath.path, "Geode.so")
|
val copiedGeodePath = File(copiedPath, "Geode.so")
|
||||||
|
|
||||||
if (externalGeodePath.exists()) {
|
if (externalGeodePath.exists()) {
|
||||||
DownloadUtils.copyFile(
|
DownloadUtils.copyFile(
|
||||||
FileInputStream(externalGeodePath),
|
externalGeodePath,
|
||||||
FileOutputStream(copiedGeodePath)
|
copiedGeodePath
|
||||||
)
|
)
|
||||||
|
|
||||||
if (copiedGeodePath.exists()) {
|
if (copiedGeodePath.exists()) {
|
||||||
println("Loading Geode from ${externalGeodePath.name}")
|
println("Loading Geode from ${externalGeodePath.name}")
|
||||||
|
|
||||||
System.load(copiedGeodePath.path)
|
System.load(copiedGeodePath.path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ import androidx.compose.animation.shrinkHorizontally
|
|||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
import androidx.compose.foundation.layout.displayCutoutPadding
|
import androidx.compose.foundation.layout.displayCutoutPadding
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.ListItem
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedCard
|
import androidx.compose.material3.OutlinedCard
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
@@ -120,9 +123,10 @@ fun LaunchNotification(cards: List<LaunchNotificationType>) {
|
|||||||
val theme = Theme.fromInt(themeOption)
|
val theme = Theme.fromInt(themeOption)
|
||||||
|
|
||||||
val backgroundOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.BLACK_BACKGROUND)
|
val backgroundOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.BLACK_BACKGROUND)
|
||||||
|
val dynamicColorOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DISABLE_USER_THEME)
|
||||||
|
|
||||||
CompositionLocalProvider(LocalTheme provides theme) {
|
CompositionLocalProvider(LocalTheme provides theme) {
|
||||||
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption) {
|
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption, dynamicColor = !dynamicColorOption) {
|
||||||
// surface is not in use, so this is unfortunately not provided
|
// surface is not in use, so this is unfortunately not provided
|
||||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
||||||
Column(
|
Column(
|
||||||
@@ -280,3 +284,26 @@ fun ForwardCompatibilityContent(modifier: Modifier = Modifier) {
|
|||||||
modifier = modifier.width(IntrinsicSize.Max)
|
modifier = modifier.width(IntrinsicSize.Max)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun FullScreenLoadingIndicator() {
|
||||||
|
val theme = Theme.DARK
|
||||||
|
val dynamicColorOption by PreferenceUtils.useBooleanPreference(PreferenceUtils.Key.DISABLE_USER_THEME)
|
||||||
|
|
||||||
|
CompositionLocalProvider(LocalTheme provides theme) {
|
||||||
|
GeodeLauncherTheme(theme = theme, blackBackground = true, dynamicColor = !dynamicColorOption) {
|
||||||
|
Surface(modifier = Modifier.fillMaxSize()) {
|
||||||
|
var showProgress by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
delay(1000L)
|
||||||
|
showProgress = true
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedVisibility(showProgress) {
|
||||||
|
CircularProgressIndicator()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -119,6 +119,12 @@ object LaunchUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class FullLauncherError(
|
||||||
|
val error: LauncherError,
|
||||||
|
val returnMessage: String,
|
||||||
|
val extendedMessage: String? = null,
|
||||||
|
) : Serializable
|
||||||
|
|
||||||
const val LAUNCHER_KEY_RETURN_ERROR = "return_error"
|
const val LAUNCHER_KEY_RETURN_ERROR = "return_error"
|
||||||
const val LAUNCHER_KEY_RETURN_MESSAGE = "return_message"
|
const val LAUNCHER_KEY_RETURN_MESSAGE = "return_message"
|
||||||
const val LAUNCHER_KEY_RETURN_EXTENDED_MESSAGE = "return_extended_message"
|
const val LAUNCHER_KEY_RETURN_EXTENDED_MESSAGE = "return_extended_message"
|
||||||
|
|||||||
Reference in new issue
Block a user