Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	app/build.gradle.kts
#	app/src/main/java/com/davidtakac/bura/common/Locale.kt
#	app/src/main/res/xml/locales_config.xml
  • Loading branch information
davidtakac committed May 9, 2024
2 parents 0dfc613 + f11cc4e commit cfb17be
Show file tree
Hide file tree
Showing 127 changed files with 1,148 additions and 788 deletions.
10 changes: 5 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ android {
applicationId = "com.davidtakac.bura"
minSdk = 28
targetSdk = 34
versionCode = 9
versionName = "1.2.0"
versionCode = 10
versionName = "1.3.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations.addAll(listOf("en", "fr", "hr", "vi", "de"))
resourceConfigurations.addAll(listOf("en", "fr", "hr", "vi", "zh-rCN", "de"))
}

buildTypes {
Expand Down Expand Up @@ -68,11 +68,11 @@ android {

dependencies {
// Core Android
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.appcompat:appcompat:1.6.1")

// Compose
implementation(platform("androidx.compose:compose-bom:2024.04.00"))
implementation(platform("androidx.compose:compose-bom:2024.05.00"))
implementation("androidx.compose.material3:material3")
implementation("androidx.navigation:navigation-compose:2.7.7")
// Previews
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/davidtakac/bura/common/Locale.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ private val supportedLocales = listOf(
Locale.forLanguageTag("fr"),
Locale.forLanguageTag("hr"),
Locale.forLanguageTag("vi"),
Locale("zh", "CN"),
Locale.forLanguageTag("de"),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ class ForecastDataDownloader(private val userAgentProvider: UserAgentProvider) {

try {
conn.requestMethod = "GET"
conn.connectTimeout = 5_000
conn.readTimeout = 5_000
conn.connectTimeout = 10_000
conn.readTimeout = 10_000
conn.setRequestProperty("User-Agent", userAgentProvider.userAgent)
if (conn.responseCode != 200) return@withContext null
BufferedReader(InputStreamReader(conn.inputStream)).use(BufferedReader::readText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private fun DrawScope.drawHorizontalAxisAndPlot(
Rect(
offset = Offset(x = args.startGutter, y = args.topGutter),
size = Size(
width = size.width - args.startGutter - args.endGutter,
width = lastX - args.startGutter,
height = size.height - args.topGutter - args.bottomGutter
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private fun DrawScope.drawHorizontalAxisAndPlot(
Rect(
offset = Offset(x = args.startGutter, y = args.topGutter),
size = Size(
width = size.width - args.startGutter - args.endGutter,
width = lastX - args.startGutter,
height = size.height - args.topGutter - args.bottomGutter
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.io.File
import java.nio.file.Files
import java.nio.file.attribute.BasicFileAttributes
import java.time.ZoneId

class FileSavedPlacesRepository(private val root: File) : SavedPlacesRepository {
Expand All @@ -31,15 +33,22 @@ class FileSavedPlacesRepository(private val root: File) : SavedPlacesRepository
val file = File(getDir(), place.location.coordinates.id)
val json = convertPlaceToJson(place)
withContext(Dispatchers.IO) { file.writeText(json) }
memoryCache?.add(place)
memoryCache?.add(0, place)
}

override suspend fun getSavedPlaces(): List<Place> {
val fromMemory = memoryCache
if (fromMemory != null) return fromMemory

val fromFiles = getDir().listFiles()?.map { convertFileToPlace(it) } ?: emptyList()
this.memoryCache = mutableListOf<Place>().apply { addAll(fromFiles) }
val fromFiles = getDir()
.listFiles()
?.sortedByDescending {
val attrs = Files.readAttributes(it.toPath(), BasicFileAttributes::class.java)
attrs.lastModifiedTime()
}
?.map { convertFileToPlace(it) }
?: emptyList()
memoryCache = mutableListOf<Place>().apply { addAll(fromFiles) }
return fromFiles
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class GetSavedPlaces(
tempDay: TemperaturePeriod,
conditionDay: ConditionPeriod
): SavedPlace.Conditions = SavedPlace.Conditions(
temp = tempDay[now]?.temperature,
temp = tempDay[now]!!.temperature,
minTemp = tempDay.minimum,
maxTemp = tempDay.maximum,
condition = conditionDay[now]?.condition
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ data class SavedPlace(
val conditions: Conditions?
) {
data class Conditions(
val temp: Temperature?,
val temp: Temperature,
val minTemp: Temperature,
val maxTemp: Temperature,
val condition: Condition
Expand Down
175 changes: 106 additions & 69 deletions app/src/main/java/com/davidtakac/bura/place/saved/SavedPlaceItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
Expand Down Expand Up @@ -65,7 +68,7 @@ fun SavedPlaceItem(
modifier: Modifier = Modifier
) {
val hapticFeedback = LocalHapticFeedback.current
Row(
Column(
Modifier
.combinedClickable(
interactionSource = remember { MutableInteractionSource() },
Expand All @@ -76,78 +79,28 @@ fun SavedPlaceItem(
onLongClick()
}
)
.then(modifier),
horizontalArrangement = Arrangement.SpaceBetween
.then(modifier)
) {
Column(
modifier = Modifier.weight(2f),
verticalArrangement = Arrangement.SpaceBetween
) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (state.selected) {
Icon(
painter = painterResource(id = R.drawable.location_on),
contentDescription = null,
modifier = Modifier
.padding(end = 2.dp)
.size(16.dp)
)
}
Text(
text = state.place.name,
style = MaterialTheme.typography.titleMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.Top) {
PlaceName(
place = state.place.name,
selected = state.selected,
modifier = Modifier.weight(1f)
)
state.conditions?.let {
TemperatureAndCondition(
temperature = it.temp,
condition = it.condition
)
}
BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.fillMaxWidth()
) {
Text(
text = state.place.countryName ?: state.place.countryCode,
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.widthIn(
max = with(LocalDensity.current) {
val maxWidth = this@BoxWithConstraints.constraints.maxWidth
(maxWidth * .75f).toDp()
}
)
)
VerticalDivider(modifier = Modifier.height(12.dp))
val formatter =
rememberDateTimeFormatter(ofPattern = R.string.date_time_pattern_hour_minute)
Text(
text = formatter.format(state.time),
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
)
}
}
}
state.conditions?.let {
Column(
Modifier.weight(1f),
verticalArrangement = Arrangement.SpaceBetween,
horizontalAlignment = Alignment.End
) {
Row(verticalAlignment = Alignment.Bottom) {
it.temp?.let {
Text(
text = it.string(),
style = MaterialTheme.typography.titleLarge
)
}
Image(
painter = it.condition.image(),
modifier = Modifier.size(28.dp),
contentDescription = null
)
}
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
CountryAndTime(
country = state.place.countryName ?: state.place.countryCode,
time = state.time,
modifier = Modifier.weight(1f)
)
state.conditions?.let {
HighLowText(
high = it.maxTemp.string(),
low = it.minTemp.string(),
Expand All @@ -158,6 +111,90 @@ fun SavedPlaceItem(
}
}

@Composable
private fun PlaceName(
place: String,
selected: Boolean,
modifier: Modifier = Modifier
) {
Row(verticalAlignment = Alignment.CenterVertically, modifier = modifier) {
if (selected) {
Icon(
painter = painterResource(id = R.drawable.location_on),
contentDescription = null,
modifier = Modifier
.padding(end = 2.dp)
.size(16.dp)
)
}
Text(
text = place,
style = MaterialTheme.typography.titleMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}

@Composable
private fun TemperatureAndCondition(
temperature: Temperature,
condition: Condition,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier.height(IntrinsicSize.Min),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.End
) {
Text(
text = temperature.string(),
style = MaterialTheme.typography.titleLarge
)
Image(
painter = condition.image(),
modifier = Modifier
.fillMaxHeight()
.aspectRatio(1f),
contentDescription = null
)
}
}

@Composable
private fun CountryAndTime(
country: String,
time: LocalTime,
modifier: Modifier = Modifier
) {
BoxWithConstraints(modifier = modifier) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp),
) {
Text(
text = country,
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.widthIn(
max = with(LocalDensity.current) {
val maxWidth = this@BoxWithConstraints.constraints.maxWidth
(maxWidth * .75f).toDp()
}
)
)
VerticalDivider(modifier = Modifier.height(12.dp))
val formatter = rememberDateTimeFormatter(ofPattern = R.string.date_time_pattern_hour_minute)
Text(
text = formatter.format(time),
style = MaterialTheme.typography.bodyMedium,
maxLines = 1,
)
}
}
}

@Preview
@Composable
private fun SavedPlaceCardPreview() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ class SearchPlaces(private val userAgentProvider: UserAgentProvider) {
}
try {
conn.requestMethod = "GET"
conn.connectTimeout = 5_000
conn.readTimeout = 5_000
conn.connectTimeout = 10_000
conn.readTimeout = 10_000
conn.setRequestProperty("User-Agent", userAgentProvider.userAgent)
if (conn.responseCode != 200) return@withContext null
BufferedReader(InputStreamReader(conn.inputStream)).use(BufferedReader::readText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ fun NowSummary(
}
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.height(IntrinsicSize.Min)
) {
CompositionLocalProvider(
Expand Down
16 changes: 8 additions & 8 deletions app/src/main/res/drawable/drizzle_for_dark.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,37 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.386,3.209A5.614,5.614 73.887,0 0,5.819 8.176,3.144 3.162,90 0,0 3.042,11.293 3.144,3.162 90,0 0,6.204 14.437l5.182,0 5.614,0a4.042,4.042 130.676,0 0,4.042 -4.042,4.042 4.042,130.676 0,0 -4.042,-4.042 4.042,4.042 130.676,0 0,-0.554 0.039,5.614 5.614,73.887 0,0 -5.06,-3.182z"
android:pathData="m11.386,3.209a5.614,5.614 90.065,0 0,-5.567 4.967,3.144 3.162,90 0,0 -2.777,3.117 3.144,3.162 90,0 0,3.161 3.144l10.797,0a4.042,4.042 90.167,0 0,4.042 -4.042,4.042 4.042,90.167 0,0 -4.042,-4.042 4.042,4.042 90.167,0 0,-0.554 0.039,5.614 5.614,90.065 0,0 -5.06,-3.182z"
android:strokeLineJoin="round"
android:strokeWidth="1.798"
android:strokeWidth="1.451"
android:fillColor="#e0e0e0"
android:strokeColor="#00000000"
android:strokeLineCap="round"/>
<path
android:pathData="m14.438,15.97c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:strokeLineJoin="round"
android:strokeWidth="2.74133"
android:strokeWidth="2.0015"
android:fillColor="#64b5f6"
android:strokeColor="#00000000"
android:strokeLineCap="round"/>
<path
android:pathData="m8.096,15.97c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:strokeLineJoin="round"
android:strokeWidth="2.74133"
android:strokeWidth="2.0015"
android:fillColor="#64b5f6"
android:strokeColor="#00000000"
android:strokeLineCap="round"/>
<path
android:pathData="m10.583,17.939c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:pathData="m10.583,17.94c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:strokeLineJoin="round"
android:strokeWidth="2.74133"
android:strokeWidth="2.0015"
android:fillColor="#64b5f6"
android:strokeColor="#00000000"
android:strokeLineCap="round"/>
<path
android:pathData="m16.93,17.939c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:pathData="m16.931,17.94c0.26,0.095 0.399,0.367 0.31,0.61l-0.707,1.941c-0.089,0.243 -0.369,0.363 -0.63,0.268 -0.26,-0.095 -0.399,-0.367 -0.31,-0.61l0.707,-1.941c0.089,-0.243 0.369,-0.363 0.63,-0.268z"
android:strokeLineJoin="round"
android:strokeWidth="2.74133"
android:strokeWidth="2.0015"
android:fillColor="#64b5f6"
android:strokeColor="#00000000"
android:strokeLineCap="round"/>
Expand Down
Loading

0 comments on commit cfb17be

Please sign in to comment.