separate launcher details for update check

This commit is contained in:
Chloe committed 2026-02-01 21:24:19 -07:00
1 parent 9d4c27ac92
commit 1d7cd9594d
6 files changed
+44 -10

No files matched your search

@@ -56,7 +56,7 @@ fun determineDisplayedCards(context: Context): List<LaunchNotificationType> {
val releaseManager = ReleaseManager.get(context) val releaseManager = ReleaseManager.get(context)
val loadAutomatically = PreferenceUtils.get(context).getBoolean(PreferenceUtils.Key.LOAD_AUTOMATICALLY) val loadAutomatically = PreferenceUtils.get(context).getBoolean(PreferenceUtils.Key.LOAD_AUTOMATICALLY)
val availableUpdate = releaseManager.availableLauncherUpdate.value val availableUpdate = releaseManager.availableLauncherUpdateTag.value
if (loadAutomatically && availableUpdate != null) { if (loadAutomatically && availableUpdate != null) {
cards.add(LaunchNotificationType.LAUNCHER_UPDATE_AVAILABLE) cards.add(LaunchNotificationType.LAUNCHER_UPDATE_AVAILABLE)
} }
@@ -116,7 +116,7 @@ class LaunchViewModel(private val application: Application): ViewModel() {
val uiState = _uiState.asStateFlow() val uiState = _uiState.asStateFlow()
val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdate val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdateTag
var loadFailure: LoadFailureInfo? = null var loadFailure: LoadFailureInfo? = null
var launchArguments: LaunchArguments? = null var launchArguments: LaunchArguments? = null
@@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
@@ -18,6 +19,7 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
@@ -253,7 +255,11 @@ fun LauncherUpdateDialog(isCancelling: Boolean, onDismiss: () -> Unit) {
fun LauncherUpdateInformation(onDismiss: () -> Unit) { fun LauncherUpdateInformation(onDismiss: () -> Unit) {
val context = LocalContext.current val context = LocalContext.current
val nextRelease = remember { ReleaseManager.get(context).availableLauncherUpdate.value } val releaseManager = remember { ReleaseManager.get(context) }
val nextReleaseName by releaseManager.availableLauncherUpdateTag.collectAsState()
val nextRelease by releaseManager.availableLauncherUpdateDetails.collectAsState()
val sheetState = rememberModalBottomSheetState() val sheetState = rememberModalBottomSheetState()
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
@@ -273,15 +279,18 @@ fun LauncherUpdateInformation(onDismiss: () -> Unit) {
}) })
} }
if (nextRelease != null) { val nextReleaseNameSaved = nextReleaseName
if (nextReleaseNameSaved != null) {
ModalBottomSheet(onDismissRequest = { onDismiss() }, sheetState = sheetState) { ModalBottomSheet(onDismissRequest = { onDismiss() }, sheetState = sheetState) {
Box(Modifier.verticalScroll(rememberScrollState())) { Box(Modifier.verticalScroll(rememberScrollState())) {
Column(modifier = Modifier.padding(horizontal = 24.dp)) { Column(modifier = Modifier.padding(horizontal = 24.dp)) {
Text( Text(
stringResource(R.string.launcher_update_name, nextRelease.release.tagName), stringResource(R.string.launcher_update_name, nextReleaseNameSaved),
style = Typography.headlineSmall, style = Typography.headlineSmall,
) )
val nextRelease = nextRelease
if (nextRelease != null) {
val releasedTime = remember { val releasedTime = remember {
DateFormat.getDateInstance().format( DateFormat.getDateInstance().format(
Date.from(nextRelease.release.publishedAt.toJavaInstant()) Date.from(nextRelease.release.publishedAt.toJavaInstant())
@@ -344,6 +353,16 @@ fun LauncherUpdateInformation(onDismiss: () -> Unit) {
) )
} }
} }
} else {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 12.dp)
) {
CircularProgressIndicator()
}
}
Spacer(modifier = Modifier.size(4.dp)) Spacer(modifier = Modifier.size(4.dp))
} }
@@ -48,8 +48,19 @@ data class LoaderPayload<T>(
data class DownloadableAsset(val url: String, val filename: String, val size: Long? = null) data class DownloadableAsset(val url: String, val filename: String, val size: Long? = null)
abstract class Downloadable { abstract class Downloadable {
/**
* Human-readable representation of the current version.
*/
abstract fun getDescription(): String abstract fun getDescription(): String
/**
* Unique value that refers to the current version, used for comparison.
*/
abstract fun getDescriptor(): Long abstract fun getDescriptor(): Long
/**
* Release download link for the current platform
*/
abstract fun getDownload(): DownloadableAsset? abstract fun getDownload(): DownloadableAsset?
} }
@@ -84,8 +84,11 @@ class ReleaseManager private constructor(
val isInUpdate: Boolean val isInUpdate: Boolean
get() = _uiState.value !is ReleaseManagerState.Failure && _uiState.value !is ReleaseManagerState.Finished get() = _uiState.value !is ReleaseManagerState.Failure && _uiState.value !is ReleaseManagerState.Finished
private val _availableLauncherUpdate = MutableStateFlow<DownloadableLauncherRelease?>(null) private val _availableLauncherUpdateTag = MutableStateFlow<String?>(null)
val availableLauncherUpdate = _availableLauncherUpdate.asStateFlow() val availableLauncherUpdateTag = _availableLauncherUpdateTag.asStateFlow()
private val _availableLauncherUpdateDetails = MutableStateFlow<DownloadableLauncherRelease?>(null)
val availableLauncherUpdateDetails = _availableLauncherUpdateDetails.asStateFlow()
private fun sendError(e: Exception) { private fun sendError(e: Exception) {
_uiState.value = ReleaseManagerState.Failure(e) _uiState.value = ReleaseManagerState.Failure(e)
@@ -252,12 +255,13 @@ class ReleaseManager private constructor(
val launcherRelease = getLatestLauncherUpdate() ?: return val launcherRelease = getLatestLauncherUpdate() ?: return
if (launcherRelease.release.tagName != BuildConfig.VERSION_NAME) { if (launcherRelease.release.tagName != BuildConfig.VERSION_NAME) {
_availableLauncherUpdate.value = launcherRelease _availableLauncherUpdateTag.value = launcherRelease.getDescription()
_availableLauncherUpdateDetails.value = launcherRelease
} }
} }
suspend fun downloadLatestLauncherUpdate(): File? { suspend fun downloadLatestLauncherUpdate(): File? {
val update = _availableLauncherUpdate.value val update = _availableLauncherUpdateDetails.value
?: getLatestLauncherUpdate() ?: getLatestLauncherUpdate()
?: return null ?: return null
@@ -53,7 +53,7 @@ class ReleaseViewModel(private val application: Application): ViewModel() {
val isInUpdate val isInUpdate
get() = ReleaseManager.get(application).isInUpdate get() = ReleaseManager.get(application).isInUpdate
val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdate val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdateTag
var hasPerformedCheck = false var hasPerformedCheck = false
private set private set