Redesign About dialog and fix button position

- Move About button above bottom spacer so it's tappable
- Replace AlertDialog with custom Dialog (dark glass card, sun emoji, centered layout)
- Add localized "Contact me" button (SunGold color)
- Mark about_made_in as non-translatable
- Add release signing config with keystore.properties
- Add ProGuard rule for findbugs annotations (R8 fix)
This commit is contained in:
Paweł Orzech 2026-01-27 16:48:01 +01:00
parent 67f2802a7d
commit d54097b15b
No known key found for this signature in database
6 changed files with 75 additions and 31 deletions

5
.gitignore vendored
View file

@ -21,6 +21,11 @@ gradle-app.setting
# Local configuration # Local configuration
local.properties local.properties
keystore.properties
# Signing
*.jks
*.keystore
# IDE # IDE
.idea/ .idea/

View file

@ -1,3 +1,5 @@
import java.util.Properties
plugins { plugins {
alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
@ -18,10 +20,24 @@ android {
versionName = "1.0" versionName = "1.0"
} }
signingConfigs {
create("release") {
val propsFile = rootProject.file("keystore.properties")
if (propsFile.exists()) {
val props = Properties().apply { load(propsFile.inputStream()) }
storeFile = file(props.getProperty("storeFile"))
storePassword = props.getProperty("storePassword")
keyAlias = props.getProperty("keyAlias")
keyPassword = props.getProperty("keyPassword")
}
}
}
buildTypes { buildTypes {
release { release {
isMinifyEnabled = true isMinifyEnabled = true
isShrinkResources = true isShrinkResources = true
signingConfig = signingConfigs.getByName("release")
proguardFiles( proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"), getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro" "proguard-rules.pro"

View file

@ -1,5 +1,6 @@
# commons-suncalc # commons-suncalc
-keep class org.shredzone.commons.suncalc.** { *; } -keep class org.shredzone.commons.suncalc.** { *; }
-dontwarn edu.umd.cs.findbugs.annotations.**
# Room # Room
-keep class * extends androidx.room.RoomDatabase -keep class * extends androidx.room.RoomDatabase

View file

@ -32,11 +32,14 @@ import androidx.compose.material.icons.rounded.KeyboardArrowDown
import androidx.compose.material.icons.rounded.MyLocation import androidx.compose.material.icons.rounded.MyLocation
import androidx.compose.material.icons.rounded.WbSunny import androidx.compose.material.icons.rounded.WbSunny
import androidx.compose.material.icons.rounded.WbTwilight import androidx.compose.material.icons.rounded.WbTwilight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -289,14 +292,9 @@ fun SunCard(
modifier = Modifier.padding(top = 8.dp) modifier = Modifier.padding(top = 8.dp)
) )
// Space for navigation bar + page indicator (80dp offset + 8dp height) + FAB Spacer(modifier = Modifier.height(24.dp))
Spacer(
modifier = Modifier
.navigationBarsPadding()
.height(112.dp)
)
// Subtle about button at the very bottom // Subtle about button
Box( Box(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
@ -310,6 +308,13 @@ fun SunCard(
.padding(vertical = 12.dp, horizontal = 24.dp) .padding(vertical = 12.dp, horizontal = 24.dp)
) )
} }
// Space for navigation bar + page indicator + FAB
Spacer(
modifier = Modifier
.navigationBarsPadding()
.height(88.dp)
)
} }
} }
} }
@ -338,30 +343,47 @@ fun SunCard(
if (showAboutDialog) { if (showAboutDialog) {
val context = LocalContext.current val context = LocalContext.current
val email = stringResource(R.string.about_email) val email = stringResource(R.string.about_email)
AlertDialog( Dialog(
onDismissRequest = { showAboutDialog = false }, onDismissRequest = { showAboutDialog = false },
title = { Text(stringResource(R.string.app_name)) }, properties = DialogProperties(usePlatformDefaultWidth = false)
text = { ) {
Column { Box(
Text(stringResource(R.string.about_made_in)) modifier = Modifier
Spacer(modifier = Modifier.height(8.dp)) .padding(horizontal = 48.dp)
.background(
color = Color.Black.copy(alpha = 0.7f),
shape = RoundedCornerShape(28.dp)
)
.padding(vertical = 32.dp, horizontal = 24.dp),
contentAlignment = Alignment.Center
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Text( Text(
text = email, text = "\u2600\uFE0F",
color = MaterialTheme.colorScheme.primary, style = MaterialTheme.typography.displayLarge
modifier = Modifier.clickable { )
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(R.string.about_made_in),
style = MaterialTheme.typography.bodyLarge,
color = Color.White
)
Spacer(modifier = Modifier.height(16.dp))
TextButton(onClick = {
context.startActivity( context.startActivity(
Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:$email")) Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:$email"))
) )
} }) {
Text(
text = stringResource(R.string.about_contact),
color = SunGold
) )
} }
},
confirmButton = {
TextButton(onClick = { showAboutDialog = false }) {
Text(stringResource(R.string.ok))
} }
} }
) }
} }
} }

View file

@ -14,8 +14,7 @@
<string name="cancel">Anuluj</string> <string name="cancel">Anuluj</string>
<string name="yearly_daylight">Daylight w roku</string> <string name="yearly_daylight">Daylight w roku</string>
<string name="about_title">O aplikacji</string> <string name="about_title">O aplikacji</string>
<string name="about_made_in">Zrobione w Warszawie przez Pawła Orzecha</string> <string name="about_contact">Napisz do mnie</string>
<string name="about_email">pawel@orzech.me</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="night_length">Długość nocy</string> <string name="night_length">Długość nocy</string>
<string name="sunrise_in">Wschód za %1$s</string> <string name="sunrise_in">Wschód za %1$s</string>

View file

@ -14,8 +14,9 @@
<string name="cancel">Cancel</string> <string name="cancel">Cancel</string>
<string name="yearly_daylight">Yearly daylight</string> <string name="yearly_daylight">Yearly daylight</string>
<string name="about_title">About</string> <string name="about_title">About</string>
<string name="about_made_in">Made in Warsaw by Paweł Orzech</string> <string name="about_made_in" translatable="false">Made with love in Warsaw, Poland</string>
<string name="about_email">pawel@orzech.me</string> <string name="about_contact">Contact me</string>
<string name="about_email" translatable="false">pawel@orzech.me</string>
<string name="ok">OK</string> <string name="ok">OK</string>
<string name="night_length">Night length</string> <string name="night_length">Night length</string>
<string name="sunrise_in">Sunrise in %1$s</string> <string name="sunrise_in">Sunrise in %1$s</string>