From 08b01d8f69dd776dd2191628846d277dc4121b1e Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Tue, 22 Oct 2024 21:44:53 +0200 Subject: [PATCH 1/7] added release states display --- .../kotlin/app/grapheneos/info/InfoApp.kt | 10 +++ .../ui/releasenotes/ReleaseNotesScreen.kt | 10 +++ .../ui/releasenotes/ReleaseNotesUiState.kt | 3 + .../ui/releasenotes/ReleaseNotesViewModel.kt | 84 ++++++++++++++++++- .../info/ui/releasenotes/ReleaseState.kt | 70 ++++++++++++++++ app/src/main/res/values/strings.xml | 9 ++ 6 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt diff --git a/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt b/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt index 960de00..9a1a00c 100644 --- a/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt +++ b/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt @@ -252,6 +252,7 @@ fun InfoApp() { ) { ReleaseNotesScreen( releaseNotesUiState.value.entries.toSortedMap().toList().asReversed(), + releaseNotesUiState.value.releaseStates.toSortedMap().toList(), { useCaches, onFinishedUpdating -> releaseNotesViewModel.updateReleaseNotes( useCaches = useCaches, @@ -268,6 +269,15 @@ fun InfoApp() { onFinishedUpdating = onFinishedUpdating, ) }, + { useCaches, onFinishedUpdating -> + releaseNotesViewModel.updateReleaseStates( + useCaches = useCaches, + showSnackbarError = { + snackbarHostState.showSnackbar(it) + }, + onFinishedUpdating = onFinishedUpdating, + ) + }, releaseNotesLazyListState, ) } diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt index d896f92..a044000 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt @@ -35,7 +35,9 @@ import kotlinx.coroutines.launch @Composable fun ReleaseNotesScreen( entries: List>, + releaseStates: List>, updateReleaseNotes: (useCaches: Boolean, finishedUpdating: () -> Unit) -> Unit, + updateReleaseStates: (useCaches: Boolean, finishedUpdating: () -> Unit) -> Unit, lazyListState: LazyListState, ) { val lifecycleOwner = LocalLifecycleOwner.current @@ -49,6 +51,7 @@ fun ReleaseNotesScreen( if (event == Lifecycle.Event.ON_START) { refreshCoroutineScope.launch { updateReleaseNotes(true) {} + updateReleaseStates(true) {} } } } @@ -105,6 +108,13 @@ fun ReleaseNotesScreen( state = lazyListState, verticalArrangement = Arrangement.Top ) { + item { + ReleaseState( + releaseStates, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp)) + } items( items = entries, key = { it.first }) { diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesUiState.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesUiState.kt index abc2ccf..4d3db4b 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesUiState.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesUiState.kt @@ -13,4 +13,7 @@ class ReleaseNotesUiState(savedStateHandle: SavedStateHandle) { } /** Unsorted release notes, use .toSortedMap().toList().asReversible() to get them in the proper order. */ val entries: MutableMap = mutableStateMapOf() + + /** Unsorted release states, use .toSortedMap().toList().asReversible() to get them in the proper order. */ + val releaseStates: MutableMap = mutableStateMapOf("stable" to "-", "beta" to "-", "alpha" to "-") } \ No newline at end of file diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt index 90972b6..81cc895 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt @@ -36,6 +36,11 @@ class ReleaseNotesViewModel( countAsInitialScroll = false, onFinishedUpdating = {}, ) + updateReleaseStates( + useCaches = true, + showSnackbarError = {}, + onFinishedUpdating = {}, + ) } fun updateReleaseNotes( @@ -121,6 +126,8 @@ class ReleaseNotesViewModel( } finally { connection.disconnect() } + + } catch (e: IOException) { val errorMessage = application.getString(R.string.update_release_notes_failed_to_create_httpsurlconnection_snackbar_message) @@ -133,4 +140,79 @@ class ReleaseNotesViewModel( } } } -} + + fun updateReleaseStates( + useCaches: Boolean, + showSnackbarError: suspend (message: String) -> Unit, + onFinishedUpdating: () -> Unit = {}, + ) { + var board = android.os.Build.BOARD + val releasePhases = arrayOf("stable", "beta", "alpha") + for (releasePhase in releasePhases) { + viewModelScope.launch(Dispatchers.IO) { + + try { + val url = URL("https://releases.grapheneos.org/$board-$releasePhase") + val connection = url.openConnection() as HttpsURLConnection + + connection.apply { + connectTimeout = 10_000 + readTimeout = 30_000 + } + + try { + + connection.useCaches = useCaches + + connection.connect() + + val responseText = String(connection.inputStream.readBytes()) + + Log.e(TAG, responseText); + + withContext(Dispatchers.Main) { + _uiState.value.releaseStates[releasePhase] = responseText.split(" ")[0] + } + + connection.disconnect() + + } catch (e: SocketTimeoutException) { + val errorMessage = + application.getString(R.string.update_release_states_socket_timeout_exception_snackbar_message) + Log.e(TAG, errorMessage, e) + viewModelScope.launch { + showSnackbarError("$errorMessage: $e") + } + } catch (e: IOException) { + val errorMessage = + application.getString(R.string.update_release_states_io_exception_snackbar_message) + Log.e(TAG, errorMessage, e) + viewModelScope.launch { + showSnackbarError("$errorMessage: $e") + } + } catch (e: UnknownServiceException) { + val errorMessage = + application.getString(R.string.update_release_states_unknown_service_exception_snackbar_message) + Log.e(TAG, errorMessage, e) + viewModelScope.launch { + showSnackbarError("$errorMessage: $e") + } + } finally { + connection.disconnect() + } + + + } catch (e: IOException) { + val errorMessage = + application.getString(R.string.update_release_states_failed_to_create_httpsurlconnection_snackbar_message) + Log.e(TAG, errorMessage, e) + viewModelScope.launch { + showSnackbarError("$errorMessage: $e") + } + } finally { + onFinishedUpdating() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt new file mode 100644 index 0000000..64000a9 --- /dev/null +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt @@ -0,0 +1,70 @@ +package app.grapheneos.info.ui.releasenotes + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.MaterialTheme.typography +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import app.grapheneos.info.R + +@Composable +fun ReleaseState(releaseStates: List>, modifier: Modifier = Modifier) { + + Row( + modifier = Modifier + .fillMaxSize(), horizontalArrangement = Arrangement.SpaceEvenly) { + Column( + ) { + ElevatedCard() { + Text( + stringResource(R.string.stable), + style = typography.titleMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + Text( + text = releaseStates.find { it.first == "stable" }?.second.toString(), + style = typography.bodyMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + } + } + Column( + ) { + ElevatedCard() { + Text( + stringResource(R.string.beta), + style = typography.titleMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + Text( + text = releaseStates.find { it.first == "beta" }?.second.toString(), + style = typography.bodyMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + } + } + Column( + ) { + ElevatedCard() { + Text( + stringResource(R.string.alpha), + style = typography.titleMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + Text( + text = releaseStates.find { it.first == "alpha" }?.second.toString(), + style = typography.bodyMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + } + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1bdbe92..6465b14 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -147,4 +147,13 @@ Copy %1$s Unable to open link. Make sure a browser is installed and enabled on your device. Info about the releases + Stable + Beta + Alpha + Socket Timeout Exception + Failed to retrieve latest release states + Unknown Service Exception + Failed to create + HttpsURLConnection + From 3e260b740cfadf9dbf275164241b9ed201f03c4c Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Tue, 22 Oct 2024 21:49:45 +0200 Subject: [PATCH 2/7] fixed variable usage of modifier --- .../grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt | 6 +----- .../app/grapheneos/info/ui/releasenotes/ReleaseState.kt | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt index a044000..6416741 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesScreen.kt @@ -109,11 +109,7 @@ fun ReleaseNotesScreen( verticalArrangement = Arrangement.Top ) { item { - ReleaseState( - releaseStates, - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 16.dp)) + ReleaseState(releaseStates) } items( items = entries, diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt index 64000a9..07bf974 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseState.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.unit.dp import app.grapheneos.info.R @Composable -fun ReleaseState(releaseStates: List>, modifier: Modifier = Modifier) { +fun ReleaseState(releaseStates: List>) { Row( modifier = Modifier From 662d0961ae66fd8c18e75c22791174310ae78739 Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Thu, 24 Oct 2024 18:41:55 +0200 Subject: [PATCH 3/7] corrected variable for device selection --- .../grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt index 81cc895..c68c7e0 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releasenotes/ReleaseNotesViewModel.kt @@ -146,7 +146,7 @@ class ReleaseNotesViewModel( showSnackbarError: suspend (message: String) -> Unit, onFinishedUpdating: () -> Unit = {}, ) { - var board = android.os.Build.BOARD + var board = android.os.Build.DEVICE val releasePhases = arrayOf("stable", "beta", "alpha") for (releasePhase in releasePhases) { viewModelScope.launch(Dispatchers.IO) { @@ -215,4 +215,4 @@ class ReleaseNotesViewModel( } } } -} \ No newline at end of file +} From eec583c529011a638b95abc50d987005ddb2410c Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Sun, 17 Aug 2025 09:56:49 +0200 Subject: [PATCH 4/7] applied code clean up and optimizations --- .../kotlin/app/grapheneos/info/InfoApp.kt | 2 +- .../info/ui/releases/ReleaseState.kt | 63 ++++++------------- .../info/ui/releases/ReleasesViewModel.kt | 7 +-- 3 files changed, 21 insertions(+), 51 deletions(-) diff --git a/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt b/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt index ab84777..627cc65 100644 --- a/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt +++ b/app/src/main/kotlin/app/grapheneos/info/InfoApp.kt @@ -286,7 +286,7 @@ fun InfoApp() { .consumeWindowInsets(innerPadding), entries = releasesUiState.value.entries.toSortedMap().toList().asReversed(), - releasesUiState.value.releaseStates.toSortedMap().toList(), + releaseStates = releasesUiState.value.releaseStates.toSortedMap().toList(), updateChangelog = { useCaches, onFinishedUpdating -> releasesViewModel.updateChangelog( useCaches = useCaches, diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt index 07bf974..7265290 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt @@ -17,53 +17,28 @@ import app.grapheneos.info.R @Composable fun ReleaseState(releaseStates: List>) { - Row( modifier = Modifier .fillMaxSize(), horizontalArrangement = Arrangement.SpaceEvenly) { - Column( - ) { - ElevatedCard() { - Text( - stringResource(R.string.stable), - style = typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) - Text( - text = releaseStates.find { it.first == "stable" }?.second.toString(), - style = typography.bodyMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) - } - } - Column( - ) { - ElevatedCard() { - Text( - stringResource(R.string.beta), - style = typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) - Text( - text = releaseStates.find { it.first == "beta" }?.second.toString(), - style = typography.bodyMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) - } - } - Column( - ) { - ElevatedCard() { - Text( - stringResource(R.string.alpha), - style = typography.titleMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) - Text( - text = releaseStates.find { it.first == "alpha" }?.second.toString(), - style = typography.bodyMedium, - modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) - ) + val releasePhases = mapOf( + "stable" to R.string.stable, + "beta" to R.string.beta, + "alpha" to R.string.alpha, + ) + for ((releasePhase, resourceId) in releasePhases) { + Column { + ElevatedCard { + Text( + text = stringResource(id = resourceId), + style = typography.titleMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + Text( + text = releaseStates.find { it.first == releasePhase }?.second.toString(), + style = typography.bodyMedium, + modifier = Modifier.padding(horizontal = 16.dp, vertical = 5.dp).align(Alignment.CenterHorizontally) + ) + } } } } diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt index 79f11ed..9079233 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt @@ -151,24 +151,22 @@ class ReleasesViewModel( val releasePhases = arrayOf("stable", "beta", "alpha") for (releasePhase in releasePhases) { viewModelScope.launch(Dispatchers.IO) { - try { val url = URL("https://releases.grapheneos.org/$board-$releasePhase") val connection = url.openConnection() as HttpsURLConnection connection.apply { + sslSocketFactory = tlsSocketFactory connectTimeout = 10_000 readTimeout = 30_000 } try { - connection.useCaches = useCaches connection.connect() val responseText = String(connection.inputStream.readBytes()) - Log.e(TAG, responseText); withContext(Dispatchers.Main) { @@ -176,7 +174,6 @@ class ReleasesViewModel( } connection.disconnect() - } catch (e: SocketTimeoutException) { val errorMessage = application.getString(R.string.update_release_states_socket_timeout_exception_snackbar_message) @@ -201,8 +198,6 @@ class ReleasesViewModel( } finally { connection.disconnect() } - - } catch (e: IOException) { val errorMessage = application.getString(R.string.update_release_states_failed_to_create_httpsurlconnection_snackbar_message) From 4ff1a6758b9cb8913bc9634495167adfc04f88f1 Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Sun, 17 Aug 2025 10:59:52 +0200 Subject: [PATCH 5/7] optimized design of release info and refactored code --- .../grapheneos/info/ui/releases/ReleaseState.kt | 17 +++++++++++------ .../info/ui/releases/ReleasesScreen.kt | 9 +++++++-- .../info/ui/releases/ReleasesViewModel.kt | 2 +- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt index 7265290..0836a00 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleaseState.kt @@ -1,9 +1,9 @@ -package app.grapheneos.info.ui.releasenotes +package app.grapheneos.info.ui.releases import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.ElevatedCard import androidx.compose.material3.MaterialTheme.typography @@ -18,16 +18,21 @@ import app.grapheneos.info.R @Composable fun ReleaseState(releaseStates: List>) { Row( - modifier = Modifier - .fillMaxSize(), horizontalArrangement = Arrangement.SpaceEvenly) { + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp) + ) { val releasePhases = mapOf( "stable" to R.string.stable, "beta" to R.string.beta, "alpha" to R.string.alpha, ) for ((releasePhase, resourceId) in releasePhases) { - Column { - ElevatedCard { + Column ( + modifier = Modifier.weight(1f), + ) { + ElevatedCard ( + modifier = Modifier.fillMaxWidth() + ) { Text( text = stringResource(id = resourceId), style = typography.titleMedium, diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt index 82ac296..74b8490 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt @@ -28,7 +28,6 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleEventObserver import androidx.lifecycle.compose.LocalLifecycleOwner import app.grapheneos.info.R -import app.grapheneos.info.ui.releasenotes.ReleaseState import app.grapheneos.info.ui.reusablecomposables.ScreenLazyColumn import kotlinx.coroutines.launch @@ -93,7 +92,13 @@ fun ReleasesScreen( verticalArrangement = Arrangement.Top ) { item { - ReleaseState(releaseStates) + Row ( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + ) { + ReleaseState(releaseStates) + } } items( items = entries, diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt index 9079233..aa5033c 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesViewModel.kt @@ -147,7 +147,7 @@ class ReleasesViewModel( showSnackbarError: suspend (message: String) -> Unit, onFinishedUpdating: () -> Unit = {}, ) { - var board = android.os.Build.DEVICE + val board = android.os.Build.DEVICE val releasePhases = arrayOf("stable", "beta", "alpha") for (releasePhase in releasePhases) { viewModelScope.launch(Dispatchers.IO) { From b6f355980b204afa011497267c746351403ab947 Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Sun, 17 Aug 2025 11:09:56 +0200 Subject: [PATCH 6/7] added updateReleaseStates to refresh functions --- .../kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt index 74b8490..790fcd4 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt @@ -53,6 +53,7 @@ fun ReleasesScreen( if (event == Lifecycle.Event.ON_START) { refreshCoroutineScope.launch { updateChangelog(true) {} + updateReleaseStates(true) {} } } } @@ -79,6 +80,7 @@ fun ReleasesScreen( state.animateToHidden() } } + updateReleaseStates(false) {} }, state = state, modifier = modifier From 52b6bf9c4342299799c0351c89ae200ca4e3a454 Mon Sep 17 00:00:00 2001 From: Dirk Baumeister Date: Sun, 17 Aug 2025 23:31:59 +0200 Subject: [PATCH 7/7] added combined reload check for changelog and release states request --- .../info/ui/releases/ReleasesScreen.kt | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt index 790fcd4..cf42f62 100644 --- a/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt +++ b/app/src/main/kotlin/app/grapheneos/info/ui/releases/ReleasesScreen.kt @@ -65,22 +65,34 @@ fun ReleasesScreen( } } - var isRefreshing by rememberSaveable { mutableStateOf(false) } + var isChangelogRefreshing by rememberSaveable { mutableStateOf(false) } + var isReleaseStatesRefreshing by rememberSaveable { mutableStateOf(false) } val state = rememberPullToRefreshState() PullToRefreshBox( - isRefreshing = isRefreshing, + isRefreshing = isChangelogRefreshing || isReleaseStatesRefreshing, onRefresh = { - isRefreshing = true + isChangelogRefreshing = true + isReleaseStatesRefreshing = true updateChangelog(false) { - isRefreshing = false + isChangelogRefreshing = false - refreshCoroutineScope.launch { - state.animateToHidden() + if (!isReleaseStatesRefreshing) { + refreshCoroutineScope.launch { + state.animateToHidden() + } + } + } + updateReleaseStates(false) { + isReleaseStatesRefreshing = false + + if (!isChangelogRefreshing) { + refreshCoroutineScope.launch { + state.animateToHidden() + } } } - updateReleaseStates(false) {} }, state = state, modifier = modifier