diff --git a/README.md b/README.md index f73306bd4..52d363aba 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,8 @@ - **China** - **AccuWeather** - **Meteo AM** +- **IPMA** +- **WeatherApi.com** - _**And more to be added**_ # 🌐 Translate the app on [Crowdin](https://crowdin.com/project/weathermaster) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 637ffa435..5e7624ad3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -32,6 +32,8 @@ val hasKeystore = keystoreFile.exists() val versionNameString = "3.8.0" +val playStore = false + android { namespace = "com.pranshulgg.weather_master_app" compileSdk { @@ -40,10 +42,14 @@ android { android.buildFeatures.buildConfig = true defaultConfig { - applicationId = "com.pranshulgg.weather_master_app" + applicationId = if (playStore) { + "com.pranshulgg.weather_master" + } else { + "com.pranshulgg.weather_master_app" + } minSdk = 26 targetSdk = 36 - versionCode = 57 + versionCode = 58 versionName = versionNameString testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -77,6 +83,12 @@ android { "APP_VERSION", "\"v${versionNameString}\"" ) + + buildConfigField( + "boolean", + "IS_PLAYSTORE_BUILD", + playStore.toString() + ) } signingConfigs { diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/core/utils/weather/computing/summary/Headlines.kt b/app/src/main/java/com/pranshulgg/weather_master_app/core/utils/weather/computing/summary/Headlines.kt index cf6c090fc..a328863bc 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/core/utils/weather/computing/summary/Headlines.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/core/utils/weather/computing/summary/Headlines.kt @@ -165,16 +165,16 @@ fun getHeadline( val tempMin = formatterTemperature(summaryData.temps.min) val tempSentence = when { - tempMax >= 35 -> + summaryData.temps.max >= 35 -> context.getString(R.string.summary_temp_template_extreme, "${tempMax}°", "${tempMin}°") - tempMax >= 25 -> + summaryData.temps.max >= 25 -> context.getString(R.string.summary_temp_template_warm, "${tempMax}°", "${tempMin}°") - tempMax >= 15 -> + summaryData.temps.max >= 15 -> context.getString(R.string.summary_temp_template_mild, "${tempMax}°", "${tempMin}°") - tempMax >= 5 -> + summaryData.temps.max >= 5 -> context.getString(R.string.summary_temp_template_cool, "${tempMax}°", "${tempMin}°") else -> diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/alerts/AlertsScreen.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/alerts/AlertsScreen.kt index 7fc659db6..acfe9b35b 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/alerts/AlertsScreen.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/alerts/AlertsScreen.kt @@ -1,5 +1,6 @@ package com.pranshulgg.weather_master_app.feature.alerts +import android.util.Log import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.WindowInsets @@ -50,6 +51,10 @@ fun AlertsScreen(navController: NavController, locationId: String) { } + if (!uiState.alerts.isNotEmpty()) { + return + } + LargeTopBarScaffold( title = "Alerts", navigationIcon = { NavigateUpBtn(navController) }, diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/DewPointHourlyCard.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/DewPointHourlyCard.kt index 1d6d96bec..25cd7de66 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/DewPointHourlyCard.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/DewPointHourlyCard.kt @@ -1,6 +1,7 @@ package com.pranshulgg.weather_master_app.feature.blocks.screens.humidity.components import android.content.Context +import android.util.Log import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -32,6 +33,7 @@ import com.pranshulgg.weather_master_app.core.utils.formatters.to12HourTimeStrin import com.pranshulgg.weather_master_app.core.utils.formatters.to24HourTimeString import com.pranshulgg.weather_master_app.feature.shared.components.CardsHeader import kotlin.collections.map +import kotlin.isNaN import kotlin.math.max import kotlin.math.roundToInt @@ -90,8 +92,13 @@ fun DewPointHourlyCard( val percentage = ((item.dewPoint!!.minus(min)).div((max - min))).times( 100 - ).roundToInt() - val barHeight = max((percentage.div(100.0)).times(140), 5.0) + ).takeIf { !it.isNaN() } ?: 0.0 + + + val barHeight = max( + (percentage.div(100.0)).times(140), + 5.0 + ) val barColor = when { item.dewPoint < 0 -> Color(0xFF1565C0) @@ -102,6 +109,15 @@ fun DewPointHourlyCard( else -> Color(0xFFC62828) } + // NEVER CRASH + val temperatureText = item.dewPoint + .takeIf { it.isFinite() } + ?.let { formatter(it) } + ?.takeIf { it.isFinite() } + ?.roundToInt() + ?.let { "$it°" } + ?: "—" + if (index == 0) Gap(horizontal = 16.dp) Column( @@ -130,7 +146,7 @@ fun DewPointHourlyCard( } Gap(5.dp) Text( - "${formatter(item.dewPoint)?.roundToInt()}°", + temperatureText, color = MaterialTheme.colorScheme.primary, style = MaterialTheme.typography.titleMedium, fontWeight = FontWeight.Bold diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/HumidityHourlyCard.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/HumidityHourlyCard.kt index 971746f90..5cba30d27 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/HumidityHourlyCard.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/blocks/screens/humidity/components/HumidityHourlyCard.kt @@ -69,7 +69,9 @@ fun HumidityHourlyCard(data: List, zoneId: String) { val item = data[index] - val barHeight = max((item.humidity!!.div(100.0)).times(140), 5.0) + val barHeight = + max((item.humidity!!.div(100.0)).times(140), 5.0).takeIf { !it.isNaN() } + ?: 5.0 val barColor = when { item.humidity < 20 -> Color(0xFFC62828) diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/editlocation/ui/EditLocationScreenDialogs.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/editlocation/ui/EditLocationScreenDialogs.kt index 58df7f4a9..3457834c1 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/editlocation/ui/EditLocationScreenDialogs.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/editlocation/ui/EditLocationScreenDialogs.kt @@ -1,6 +1,8 @@ package com.pranshulgg.weather_master_app.feature.editlocation.ui import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.pranshulgg.weather_master_app.R import com.pranshulgg.weather_master_app.core.ui.components.TextAlertDialog import com.pranshulgg.weather_master_app.feature.editlocation.EditLocationViewModel import com.pranshulgg.weather_master_app.feature.locations.LocationsScreenViewModel @@ -18,8 +20,8 @@ object EditLocationScreenDialogs { show = uiState.isConfirmationDialogOpen, onConfirm = onConfirm, onDismiss = viewModel::hideConfirmationDialog, - title = "Delete Location", - message = "Are you sure you want to delete this location?" + title = stringResource(R.string.confirm_delete_location), + message = stringResource(R.string.alert_delete_location_secondary) ) } } \ No newline at end of file diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/intro/IntroScreen.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/intro/IntroScreen.kt index ed3976e93..c63ec4290 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/intro/IntroScreen.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/intro/IntroScreen.kt @@ -156,10 +156,14 @@ fun IntroScreen(navController: NavController) { contentPadding = ButtonDefaults.contentPaddingFor(btnSize), shapes = ButtonDefaults.shapes() ) { - Text("Enable Location", style = ButtonDefaults.textStyleFor(btnSize)) + Text( + if (isLoading) "Loading..." else "Enable Location", + style = ButtonDefaults.textStyleFor(btnSize) + ) } Gap(12.dp) OutlinedButton( + enabled = !isLoading, onClick = { navController.navigate(NavRoutes.SEARCH) }, diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/locations/ui/LocationsScreenDialogs.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/locations/ui/LocationsScreenDialogs.kt index 97ac2fb49..2634d8d66 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/locations/ui/LocationsScreenDialogs.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/locations/ui/LocationsScreenDialogs.kt @@ -1,6 +1,8 @@ package com.pranshulgg.weather_master_app.feature.locations.ui import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.pranshulgg.weather_master_app.R import com.pranshulgg.weather_master_app.core.ui.components.TextAlertDialog import com.pranshulgg.weather_master_app.feature.locations.LocationsScreenViewModel import com.pranshulgg.weather_master_app.feature.shared.WeatherViewModel @@ -21,7 +23,7 @@ fun LocationScreenConfirmationDialog( viewModel.hideConfirmationDialog() }, onDismiss = viewModel::hideConfirmationDialog, - title = "Delete Location", - message = "Are you sure you want to delete this location?" + title = stringResource(R.string.confirm_delete_location), + message = stringResource(R.string.alert_delete_location_secondary) ) } \ No newline at end of file diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreen.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreen.kt index 7d6dfe9b5..54463546c 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreen.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreen.kt @@ -65,7 +65,8 @@ data class MainScreenUiState( val isNewVersionAvailable: Boolean = false, val lastestVersionUrl: String = "https://github.com/PranshulGG/WeatherMaster/releases/latest", val isUnsupportedSourceDialogOpen: Boolean = false, - val isChangelogSheetOpen: Boolean = false + val isChangelogSheetOpen: Boolean = false, + val isGooglePlayStoreRelease: Boolean = BuildConfig.IS_PLAYSTORE_BUILD ) @OptIn(ExperimentalMaterial3Api::class) diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreenViewModel.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreenViewModel.kt index 62b80ceb3..f273ebe90 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreenViewModel.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/main/MainScreenViewModel.kt @@ -25,7 +25,9 @@ class MainScreenViewModel @Inject constructor( init { viewModelScope.launch { - checkForUpdates() + if (!_uiState.value.isGooglePlayStoreRelease) { + checkForUpdates() + } } } diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/settings/SettingsScreen.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/settings/SettingsScreen.kt index 6a62f6f22..300e5c8f8 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/settings/SettingsScreen.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/settings/SettingsScreen.kt @@ -1,31 +1,49 @@ package com.pranshulgg.weather_master_app.feature.settings +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.BasicAlertDialog +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ListItem +import androidx.compose.material3.ListItemDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController 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.LargeTopBarScaffold import com.pranshulgg.weather_master_app.core.ui.components.NavigateUpBtn 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.WeatherIconBox import com.pranshulgg.weather_master_app.core.ui.navigation.NavRoutes import com.pranshulgg.weather_master_app.core.utils.locale.getCurrentAppLocale +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SettingsScreen(navController: NavController) { val uriHandler = LocalUriHandler.current + var isDonationDialogOpen by remember { mutableStateOf(false) } + LargeTopBarScaffold( title = stringResource(R.string.settings), navigationIcon = { NavigateUpBtn(navController) }, @@ -47,12 +65,12 @@ fun SettingsScreen(navController: NavController) { description = stringResource(R.string.setting_appearance_secondary), onClick = { navController.navigate(NavRoutes.APPEARANCE) } ), -// SettingTile.ActionTile( -// leading = { SettingsTileIcon(R.drawable.favorite_24px) }, -// title = "Support", -// description = "If you enjoy the app, consider supporting its development", -// onClick = { uriHandler.openUri("https://github.com/sponsors/PranshulGG?frequency=one-time&sponsor=PranshulGG") } -// ) + SettingTile.ActionTile( + leading = { SettingsTileIcon(R.drawable.favorite_24px) }, + title = "Support", + description = "If you enjoy the app, consider supporting its development", + onClick = { isDonationDialogOpen = true } + ) ) ) @@ -101,4 +119,45 @@ fun SettingsScreen(navController: NavController) { ) } } + + DialogBasic( + show = isDonationDialogOpen, + title = "Donate", + dismissText = stringResource(R.string.action_cancel), + showOnlyDismissAction = true, + onConfirm = {}, + onDismiss = { isDonationDialogOpen = false }, + ) { + Column( + ) { + DonateListItem( + "Ko-fi", + "Ko-fi.com/pranshulgg", + R.drawable.kofi_symbol + ) { uriHandler.openUri("https://ko-fi.com/pranshulgg") } + DonateListItem( + "Liberapay", + "liberapay.com/PranshulGG", + R.drawable.liberapay_logo, + ) { uriHandler.openUri("https://liberapay.com/PranshulGG") } + DonateListItem( + "Github sponsors", + "github.com/sponsors/PranshulGG", + R.drawable.gitub_logo_colored, + ) { uriHandler.openUri("https://github.com/sponsors/PranshulGG?frequency=one-time&sponsor=PranshulGG") } + } + } +} + +@Composable +private fun DonateListItem(headline: String, description: String, icon: Int, onClick: () -> Unit) { + ListItem( + colors = ListItemDefaults.colors(containerColor = Color.Transparent), + leadingContent = { WeatherIconBox(icon, size = 28.dp) }, + headlineContent = { Text(headline) }, + supportingContent = { Text(description) }, + modifier = Modifier + .clickable(onClick = onClick) + .padding(horizontal = 14.dp) + ) } \ No newline at end of file diff --git a/app/src/main/java/com/pranshulgg/weather_master_app/feature/shared/ui/SharedDialogs.kt b/app/src/main/java/com/pranshulgg/weather_master_app/feature/shared/ui/SharedDialogs.kt index 8ec051e05..a27f2bcba 100644 --- a/app/src/main/java/com/pranshulgg/weather_master_app/feature/shared/ui/SharedDialogs.kt +++ b/app/src/main/java/com/pranshulgg/weather_master_app/feature/shared/ui/SharedDialogs.kt @@ -44,20 +44,4 @@ 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() -// } -// } } \ No newline at end of file diff --git a/app/src/main/res/drawable/gitub_logo_colored.png b/app/src/main/res/drawable/gitub_logo_colored.png new file mode 100644 index 000000000..d44393a07 Binary files /dev/null and b/app/src/main/res/drawable/gitub_logo_colored.png differ diff --git a/app/src/main/res/drawable/kofi_symbol.png b/app/src/main/res/drawable/kofi_symbol.png new file mode 100644 index 000000000..dd55a5e2d Binary files /dev/null and b/app/src/main/res/drawable/kofi_symbol.png differ diff --git a/app/src/main/res/drawable/liberapay_logo.png b/app/src/main/res/drawable/liberapay_logo.png new file mode 100644 index 000000000..e738da1b4 Binary files /dev/null and b/app/src/main/res/drawable/liberapay_logo.png differ diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index 3100e5efa..bd82a65ce 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -277,11 +277,11 @@ Onko sinulla säätietojen tarjoaja lisättäväksi? Voit toivoa sitä tästä Toivo tarjoajaa %1$s ja muut - Tuuli: + Tuuli: %1$s %1$s tuntia Tuloksia ei löytynyt Luvassa %1$s päivällä ja yöllä. - Päivällä luvassa poutaa, yöksi %2$s. + Päivällä luvassa %1$s, yöllä %2$s. Päivällä on luvassa sadetta noin kello %1$s %2$s todennäköisyydellä. Yöllä on %3$s todennäköisyys sateeseen noin kello %4$s. Päivällä on luvassa sadetta noin kello %1$s %2$s todennäköisyydellä. Yöllä on %1$s todennäköisyys sateeseen noin kello %2$s. diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index e06a85adf..8a5ac8cbe 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -183,7 +183,7 @@ יישום זה שולח התראה ברקע כאשר יש עדכוני מזג אוויר התראה %1$s שעות - שעה + %1$s שעה מיטוב הסוללה כבר בהתעלמות הגדרות נוספות מרווח זמן בין עדכונים diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index c00ae5617..8bc406c21 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -95,7 +95,7 @@ Apagar Não é possível eliminar o local padrão Aparência da aplicação - Sensação térmica + Sensação térmica %1$s Máx.: %1$s Mín.: %1$s Resultados da pesquisa fornecido por %1$s diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ada4b36b3..eb650b1ec 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -11,10 +11,10 @@ 降雨時長 現在 今天 - 請在 %1$d 分鐘後重新整理 - 發生錯誤。請再試一次 - 月亮 - 太陽 + 請稍候 %1$d 分鐘 刷新後 + 發生錯誤。 請再試一次 + 月相 + 週日 濕度 氣壓 風速 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 992e37242..51b244e05 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -395,6 +395,20 @@ Alerts + Dry and comfortable + Comfortable + Sticky + Muggy + Uncomfortable + + Requires restart + Latitude + Longitude + Support + If you enjoy the app, consider supporting its development + Your device language + System + diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 992b24c2f..f88a37e6e 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -1,4 +1,4 @@ -

WeatherMaster inspired by the Google Pixel weather app, but with more features

+

WeatherMasterInspired by the Google Pixel weather app, but with more features


Features both the Pixel Weather-inspired design and the original Froggy style, with summaries, multiple weather and search providers, personalization options, and more.


@@ -17,5 +17,7 @@
  • China
  • AccuWeather
  • Meteo AM
  • +
  • IPMA
  • +
  • WeatherApi.com
  • And more to be added