add Changelog bottom sheet

This commit is contained in:
PranshulGG committed 2026-08-01 14:50:04 +05:30
1 parent 0445ac0359
commit 07730aed97
8 files changed
+203 -8

No files matched your search

@@ -4,14 +4,12 @@ import com.pranshulgg.weather_master_app.core.model.domain.AppException
import com.pranshulgg.weather_master_app.core.model.domain.location.Location
import com.pranshulgg.weather_master_app.core.model.weather.WeatherResult
import com.pranshulgg.weather_master_app.core.model.weather.WeatherResultType
import com.pranshulgg.weather_master_app.core.network.sources.weather.accu.AccuApi
import com.pranshulgg.weather_master_app.core.network.sources.weather.accu.json.bundle.AccuWeatherBundle
import com.pranshulgg.weather_master_app.core.network.sources.weather.meteoam.json.bundle.MeteoamWeatherBundle
import com.pranshulgg.weather_master_app.core.utils.weather.cache.isWeatherCacheSafe
import com.pranshulgg.weather_master_app.core.utils.weather.cache.shouldReturnWeatherCache
import com.pranshulgg.weather_master_app.data.local.dao.location.LocationsDao
import com.pranshulgg.weather_master_app.data.local.dao.weather.WeatherDao
import com.pranshulgg.weather_master_app.data.local.mapper.weather.sources.accu.toDomain
import com.pranshulgg.weather_master_app.data.local.mapper.locations.toDomain
import com.pranshulgg.weather_master_app.data.local.mapper.weather.sources.meteoam.toDomain
import com.pranshulgg.weather_master_app.data.local.mapper.weather.toCurrentWeatherEntity
import com.pranshulgg.weather_master_app.data.local.mapper.weather.toDailyWeatherEntity
@@ -22,6 +22,7 @@ import androidx.compose.ui.platform.LocalWindowInfo
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.navigation.NavController
import com.pranshulgg.weather_master_app.BuildConfig
import com.pranshulgg.weather_master_app.R
import com.pranshulgg.weather_master_app.core.model.domain.airquality.AirQuality
import com.pranshulgg.weather_master_app.core.model.domain.alerts.Alert
@@ -30,6 +31,7 @@ import com.pranshulgg.weather_master_app.core.model.domain.weather.Weather
import com.pranshulgg.weather_master_app.core.model.domain.weather.WeatherBlock
import com.pranshulgg.weather_master_app.core.model.domain.weather.WeatherUnits
import com.pranshulgg.weather_master_app.core.model.sources.WeatherSource
import com.pranshulgg.weather_master_app.core.prefs.helper.PreferencesHelper
import com.pranshulgg.weather_master_app.core.ui.navigation.NavRoutes
import com.pranshulgg.weather_master_app.core.ui.snackbar.SnackbarManager
import com.pranshulgg.weather_master_app.feature.intro.IntroScreen
@@ -39,6 +41,7 @@ import com.pranshulgg.weather_master_app.feature.main.ui.MainScreenDialogs
import com.pranshulgg.weather_master_app.feature.main.ui.NavigationDrawer
import com.pranshulgg.weather_master_app.feature.shared.WeatherViewModel
import com.pranshulgg.weather_master_app.feature.shared.ui.SharedBottomSheet
import com.pranshulgg.weather_master_app.feature.shared.ui.SharedDialogs
import kotlinx.coroutines.launch
data class MainScreenWeatherUiState(
@@ -61,7 +64,8 @@ data class MainScreenUiState(
val isWeatherSourcesInfoForLocationSheetOpen: Boolean = false,
val isNewVersionAvailable: Boolean = false,
val lastestVersionUrl: String = "https://github.com/PranshulGG/WeatherMaster/releases/latest",
val isUnsupportedSourceDialogOpen: Boolean = false
val isUnsupportedSourceDialogOpen: Boolean = false,
val isChangelogSheetOpen: Boolean = false
)
@OptIn(ExperimentalMaterial3Api::class)
@@ -71,8 +75,7 @@ fun MainScreen(navController: NavController, weatherViewModel: WeatherViewModel)
val viewModel: MainScreenViewModel = hiltViewModel()
val mainScreenUiState = viewModel.uiState.value
val uriHandler = LocalUriHandler.current
val savedVersion = PreferencesHelper.getString("saved_version")
if (uiState.locations.isEmpty()) {
IntroScreen(navController)
@@ -131,6 +134,14 @@ fun MainScreen(navController: NavController, weatherViewModel: WeatherViewModel)
}
}
LaunchedEffect(Unit) {
if (BuildConfig.APP_VERSION != savedVersion) {
viewModel.showChangelogSheet()
PreferencesHelper.setString("saved_version", BuildConfig.APP_VERSION)
}
}
NavigationDrawer(
drawerContent = {
LocationsScreen(
@@ -188,6 +199,13 @@ fun MainScreen(navController: NavController, weatherViewModel: WeatherViewModel)
onDismiss =
viewModel::hideUnsupportedSelectedSourceDialog,
onConfirm = { viewModel.showWeatherSourcesForLocationSheet(uiState.isLoading) })
// CHANGELOG DIALOG
SharedBottomSheet.ChangelogBottomSheet(
sheetState,
onDismiss = viewModel::hideChangelogSheet,
show = mainScreenUiState.isChangelogSheetOpen
)
}
@@ -79,4 +79,12 @@ class MainScreenViewModel @Inject constructor(
_uiState.value = _uiState.value.copy(isNewVersionAvailable = false)
}
fun hideChangelogSheet() {
_uiState.value = _uiState.value.copy(isChangelogSheetOpen = false)
}
fun showChangelogSheet() {
_uiState.value = _uiState.value.copy(isChangelogSheetOpen = true)
}
}
@@ -21,4 +21,5 @@ object MainScreenDialogs {
message = "The currently selected source is not supported in your region. Please choose a different source"
)
}
}
@@ -9,15 +9,22 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.IconButton
import androidx.compose.material3.IconButtonDefaults
import androidx.compose.material3.ListItem
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SheetValue
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.rememberBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
@@ -37,8 +44,11 @@ import com.pranshulgg.weather_master_app.core.ui.components.SettingsTileIcon
import com.pranshulgg.weather_master_app.core.ui.components.Symbol
import com.pranshulgg.weather_master_app.core.ui.navigation.NavRoutes
import com.pranshulgg.weather_master_app.core.ui.theme.ShapeRadius
import com.pranshulgg.weather_master_app.feature.shared.ui.SharedBottomSheet
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AboutScreen(navController: NavController) {
val context = LocalContext.current
@@ -48,6 +58,15 @@ fun AboutScreen(navController: NavController) {
val isLoadingNewVersion = viewModel.loading
val uriHandler = LocalUriHandler.current
var isChangelogSheetOpen by remember { mutableStateOf(false) }
val sheetState = rememberBottomSheetState(
initialValue = SheetValue.Hidden,
enabledValues = setOf(SheetValue.Expanded, SheetValue.Hidden)
)
LargeTopBarScaffold(
title = stringResource(R.string.setting_about_app),
navigationIcon = { NavigateUpBtn(navController) },
@@ -94,9 +113,11 @@ fun AboutScreen(navController: NavController) {
onClick = { uriHandler.openUri("https://github.com/PranshulGG/WeatherMaster/issues/new") }
),
SettingTile.ActionTile(
leading = { SettingsTileIcon(R.drawable.github_invertocat_black) },
leading = { SettingsTileIcon(R.drawable.text_snippet_24px) },
title = stringResource(R.string.about_changelog),
onClick = { uriHandler.openUri("https://github.com/PranshulGG/WeatherMaster/releases/latest") }
onClick = {
isChangelogSheetOpen = true
}
),
SettingTile.ActionTile(
leading = { SettingsTileIcon(R.drawable.mail_24px) },
@@ -109,6 +130,12 @@ fun AboutScreen(navController: NavController) {
)
}
}
SharedBottomSheet.ChangelogBottomSheet(
sheetState,
onDismiss = { isChangelogSheetOpen = false },
show = isChangelogSheetOpen
)
}
@Composable
@@ -0,0 +1,95 @@
package com.pranshulgg.weather_master_app.feature.shared.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
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 com.pranshulgg.weather_master_app.BuildConfig
import com.pranshulgg.weather_master_app.R
import com.pranshulgg.weather_master_app.core.ui.components.Gap
@Composable
fun ChangelogContent(hideSheet: () -> Unit) {
Text(
"Changelog ${BuildConfig.APP_VERSION}",
modifier = Modifier.padding(16.dp),
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.onSurface
)
HorizontalDivider()
Gap(5.dp)
ChangelogBox {
ChangelogHeader("New stuff")
ChangelogText("Edit location names")
ChangelogText("Option to choose Air quality and Alert sources")
ChangelogText("New source: WeatherApi.com")
ChangelogText("Changelog dialog should appear on first time install of every new release")
}
ChangelogBox {
ChangelogHeader("Fixed")
ChangelogText("AccuWeather redundant calls for location keys")
ChangelogText("Fixed null value crashes for NWS")
ChangelogText("Search results without time zone should not show")
ChangelogText("Main hourly forecast should also include next day hours #974")
}
ChangelogBox {
ChangelogHeader("Improvements")
ChangelogText("Summary now only shows for the upcoming events and dismisses the past hours")
ChangelogText("Improved source picker")
}
Button(
onClick = hideSheet, modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
shapes = ButtonDefaults.shapes()
) {
Text(stringResource(R.string.action_ok))
}
}
@Composable
private fun ChangelogBox(content: @Composable () -> Unit) {
Column(Modifier.padding(vertical = 5.dp, horizontal = 16.dp)) {
content()
}
}
@Composable
private fun ChangelogText(text: String) {
Row(verticalAlignment = Alignment.Top, horizontalArrangement = Arrangement.spacedBy(5.dp)) {
Text(
"•",
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.bodyMedium
)
Text(
text,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyMedium
)
}
}
@Composable
private fun ChangelogHeader(text: String) {
Text(
"# $text",
color = MaterialTheme.colorScheme.secondary,
style = MaterialTheme.typography.titleLarge,
modifier = Modifier.padding(bottom = 3.dp)
)
}
@@ -27,6 +27,7 @@ import com.pranshulgg.weather_master_app.core.ui.components.SettingSection
import com.pranshulgg.weather_master_app.core.ui.components.SettingTile
import com.pranshulgg.weather_master_app.core.ui.components.SettingsTileIcon
import com.pranshulgg.weather_master_app.core.ui.components.Symbol
import com.pranshulgg.weather_master_app.feature.shared.components.ChangelogContent
object SharedBottomSheet {
@OptIn(ExperimentalMaterial3Api::class)
@@ -105,5 +106,27 @@ object SharedBottomSheet {
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ChangelogBottomSheet(
sheetState: SheetState,
show: Boolean,
onDismiss: () -> Unit
) {
if (show) {
ActionBottomSheet(
sheetState = sheetState,
onCancel = { onDismiss() },
onConfirm = { },
showActions = false,
confirmText = stringResource(R.string.action_save),
cancelText = stringResource(R.string.action_cancel)
) { hide ->
ChangelogContent(hide)
}
}
}
}
@@ -1,7 +1,15 @@
package com.pranshulgg.weather_master_app.feature.shared.ui
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.pranshulgg.weather_master_app.R
import com.pranshulgg.weather_master_app.core.ui.components.DialogBasic
import com.pranshulgg.weather_master_app.core.ui.components.TextAlertDialog
import com.pranshulgg.weather_master_app.feature.shared.components.ChangelogContent
object SharedDialogs {
@@ -35,4 +43,21 @@ object SharedDialogs {
)
}
// @Composable
// fun ChangelogDialog(
// show: Boolean,
// onDismiss: () -> Unit,
// version: String,
// ) {
// DialogBasic(
// show = show,
// onDismiss = onDismiss,
// title = "Change Log $version",
// dismissText = stringResource(R.string.action_ok),
// showOnlyDismissAction = true
// ) {
// ChangelogContent()
// }
// }
}