Skip to content
This repository was archived by the owner on Jun 6, 2025. It is now read-only.

Commit 73864f1

Browse files
[v1.0.1] Upgrade to v1.0.1 (#2)
* [v1.0.1] Fix bug in version 1.0.1 * [v1.0.1] Change README.md
1 parent 9566c3f commit 73864f1

24 files changed

+217
-37
lines changed

.idea/deploymentTargetDropDown.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,25 @@ I want to say thanks for those people to help me to make this app.
2020
```kotlin
2121
BASE_URL=https://api.openweathermap.org/data/2.5/
2222
API_KEY=API_KEY // Fill your open weather api key in here
23-
MAPS_API_KEY= GOOGLE_MAPS_API_KEY // Fill your google maps api key in here
23+
MAPS_API_KEY=GOOGLE_MAPS_API_KEY // Fill your google maps api key in here
2424
```
2525

2626
## :camera: Screenshots
2727

2828
| Light mode | Dark mode |
2929
| :---: | :---: |
3030
| ![Home Light](image/home_light.png "Home Light") | ![Home Dark](image/home_dark.png "Home Dark") |
31+
| ![Seven Days Light](image/seven_days_light.png "Seven Days Light") | ![Seven Days Light](image/seven_days_dark.png "Seven Days Light") |
3132
| ![Search By Map Light](image/search_by_map_light.png "Search By Map Light") | ![Search By Map Dark](image/search_by_map_dark.png "Search By Map Dark") |
33+
| ![Drawer Light](image/drawer_light.png "Drawer Light") | ![Drawer Dark](image/drawer_dark.png "Drawer Dark") |
34+
| ![Search By Text Light](image/search_by_text_light.png "Search By Text Light") | ![Search By Text Dark](image/search_by_text_dark.png "Search By Text Dark") |
3235

3336
## :blue_book: Features
3437

35-
- Show the current weather by location.
38+
- Show the current weather by location or name.
39+
- Show the seven days weather by location or name.
3640
- Choice the location you want by using Google Map.
41+
- Search location by address name by using Google Places.
3742
- Support dark mode.
3843
- Support dynamic material from Android 13 and above.
3944
- Support English and Vietnamese.

app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ android {
2121
minSdk = 21
2222
targetSdkPreview = "Tiramisu"
2323
versionCode = 1
24-
versionName = "1.0.0"
24+
versionName = "1.0.1"
2525

2626
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2727
vectorDrawables {

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
android:exported="true"
3030
android:screenOrientation="sensorPortrait"
3131
android:theme="@style/Theme.Weapose"
32+
android:windowSoftInputMode="adjustResize"
3233
tools:ignore="LockedOrientationActivity">
3334
<intent-filter>
3435
<action android:name="android.intent.action.MAIN" />

app/src/main/java/com/minhdtm/example/weapose/data/repositories/LocationRepositoryImpl.kt

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Context
55
import android.location.Address
66
import android.location.Geocoder
77
import android.os.Build
8+
import androidx.compose.ui.text.intl.Locale
89
import com.google.android.gms.location.LocationRequest
910
import com.google.android.gms.location.LocationServices
1011
import com.google.android.gms.maps.model.LatLng
@@ -78,7 +79,13 @@ class LocationRepositoryImpl @Inject constructor(
7879
message = context.getString(R.string.error_message_current_address_is_not_found)
7980
)
8081

81-
val geo = Geocoder(context, Locale.ENGLISH)
82+
val getSystemLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
83+
context.resources.configuration.locales[0]
84+
} else {
85+
context.resources.configuration.locale
86+
}
87+
88+
val geo = Geocoder(context, getSystemLocale)
8289
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
8390
geo.getFromLocation(latLng.latitude, latLng.longitude, 1) { listAddress ->
8491
if (listAddress.isEmpty()) {
@@ -107,7 +114,13 @@ class LocationRepositoryImpl @Inject constructor(
107114
message = context.getString(R.string.error_message_current_address_is_not_found)
108115
)
109116

110-
val geo = Geocoder(context, Locale.ENGLISH)
117+
val getSystemLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
118+
context.resources.configuration.locales[0]
119+
} else {
120+
context.resources.configuration.locale
121+
}
122+
123+
val geo = Geocoder(context, getSystemLocale)
111124
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
112125
geo.getFromLocationName(text, 1) { listAddress ->
113126
if (listAddress.isEmpty()) {
@@ -135,7 +148,13 @@ class LocationRepositoryImpl @Inject constructor(
135148
-1, context.getString(R.string.error_message_address_is_not_found)
136149
)
137150

138-
val geo = Geocoder(context, Locale.ENGLISH)
151+
val getSystemLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
152+
context.resources.configuration.locales[0]
153+
} else {
154+
context.resources.configuration.locale
155+
}
156+
157+
val geo = Geocoder(context, getSystemLocale)
139158
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
140159
geo.getFromLocation(latLng.latitude, latLng.longitude, 1) { listAddress ->
141160
if (listAddress.isEmpty()) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.minhdtm.example.weapose.presentation.broadcast
2+
3+
import android.content.BroadcastReceiver
4+
import android.content.Context
5+
import android.content.Intent
6+
import androidx.compose.ui.text.intl.Locale
7+
8+
class LocaleChangeBroadcast constructor(
9+
private val onChangeLocale: (Locale) -> Unit,
10+
) : BroadcastReceiver() {
11+
override fun onReceive(p0: Context?, p1: Intent?) {
12+
val locale = Locale.current
13+
onChangeLocale.invoke(locale)
14+
}
15+
}

app/src/main/java/com/minhdtm/example/weapose/presentation/model/DayWeatherViewData.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import com.minhdtm.example.weapose.data.model.Daily
66
import com.minhdtm.example.weapose.presentation.utils.Constants
77
import com.minhdtm.example.weapose.presentation.utils.toDateTime
88
import com.minhdtm.example.weapose.presentation.utils.toIcon
9-
import com.minhdtm.example.weapose.presentation.utils.toUVIndexAttention
109
import javax.inject.Inject
1110

1211
data class DayWeatherViewData(
@@ -17,7 +16,7 @@ data class DayWeatherViewData(
1716
val minTemp: Double,
1817
val windSpeed: String,
1918
val humidity: Int,
20-
val uvIndex: String,
19+
val uvIndex: Double,
2120
val sunrise: String,
2221
val sunset: String,
2322
) : ViewData()
@@ -35,7 +34,7 @@ class SevenWeatherViewDataMapper @Inject constructor() : DataModelMapper<Daily,
3534
val minTemp = model.temp?.min ?: 0.0
3635
val windSpeed = String.format("%.1f", model.windSpeed?.times(3.6) ?: 0.0)
3736
val humidity = model.humidity ?: 0
38-
val uvIndex = "${model.uvi?.toUVIndexAttention()}, ${model.uvi ?: 0.0}"
37+
val uvIndex = model.uvi ?: 0.0
3938
val sunrise = model.sunrise?.times(1000)?.toDateTime(Constants.DateFormat.HH_mm) ?: ""
4039
val sunset = model.sunset?.times(1000)?.toDateTime(Constants.DateFormat.HH_mm) ?: ""
4140

app/src/main/java/com/minhdtm/example/weapose/presentation/ui/WeatherApp.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
package com.minhdtm.example.weapose.presentation.ui
22

33
import android.annotation.SuppressLint
4+
import android.content.Intent
5+
import android.content.IntentFilter
46
import androidx.compose.animation.ExperimentalAnimationApi
57
import androidx.compose.foundation.Image
68
import androidx.compose.foundation.gestures.detectTapGestures
79
import androidx.compose.foundation.isSystemInDarkTheme
810
import androidx.compose.foundation.layout.*
911
import androidx.compose.material3.*
1012
import androidx.compose.runtime.Composable
13+
import androidx.compose.runtime.DisposableEffect
1114
import androidx.compose.runtime.SideEffect
1215
import androidx.compose.ui.Alignment
1316
import androidx.compose.ui.Modifier
1417
import androidx.compose.ui.graphics.Color
1518
import androidx.compose.ui.input.pointer.pointerInput
19+
import androidx.compose.ui.platform.LocalContext
1620
import androidx.compose.ui.platform.LocalFocusManager
1721
import androidx.compose.ui.res.painterResource
1822
import androidx.compose.ui.res.stringResource
@@ -21,6 +25,7 @@ import com.google.accompanist.navigation.animation.AnimatedNavHost
2125
import com.google.accompanist.systemuicontroller.rememberSystemUiController
2226
import com.minhdtm.example.weapose.BuildConfig
2327
import com.minhdtm.example.weapose.R
28+
import com.minhdtm.example.weapose.presentation.broadcast.LocaleChangeBroadcast
2429
import com.minhdtm.example.weapose.presentation.component.NavigationDrawerLabel
2530

2631
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@@ -31,13 +36,24 @@ fun WeatherApp(appState: WeatherAppState = rememberWeatherAppState()) {
3136
val darkIcons = isSystemInDarkTheme()
3237

3338
val localFocusManager = LocalFocusManager.current
39+
val localContext = LocalContext.current
3440

3541
SideEffect {
3642
if (!appState.isCustomDarkMode) {
3743
systemUiController.setSystemBarsColor(color = Color.Transparent, darkIcons = !darkIcons)
3844
}
3945
}
4046

47+
DisposableEffect(true) {
48+
val broadcast = LocaleChangeBroadcast(appState::onLocaleChange)
49+
50+
localContext.registerReceiver(broadcast, IntentFilter(Intent.ACTION_LOCALE_CHANGED))
51+
52+
onDispose {
53+
localContext.unregisterReceiver(broadcast)
54+
}
55+
}
56+
4157
ModalNavigationDrawer(
4258
drawerState = appState.drawer,
4359
modifier = Modifier.pointerInput(Unit) {

app/src/main/java/com/minhdtm/example/weapose/presentation/ui/WeatherAppState.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import androidx.compose.material3.*
1313
import androidx.compose.runtime.Composable
1414
import androidx.compose.runtime.remember
1515
import androidx.compose.runtime.rememberCoroutineScope
16+
import androidx.compose.ui.text.intl.Locale
1617
import androidx.hilt.navigation.compose.hiltViewModel
1718
import androidx.navigation.*
1819
import androidx.navigation.compose.currentBackStackEntryAsState
@@ -28,7 +29,10 @@ import com.minhdtm.example.weapose.presentation.ui.settings.Settings
2829
import com.minhdtm.example.weapose.presentation.ui.sevendaysweather.SevenDaysWeather
2930
import com.minhdtm.example.weapose.presentation.utils.Constants
3031
import kotlinx.coroutines.CoroutineScope
32+
import kotlinx.coroutines.channels.Channel
33+
import kotlinx.coroutines.flow.Flow
3134
import kotlinx.coroutines.flow.StateFlow
35+
import kotlinx.coroutines.flow.receiveAsFlow
3236
import kotlinx.coroutines.launch
3337

3438
sealed class Screen(val route: String) {
@@ -256,6 +260,9 @@ class WeatherAppState(
256260
return route in listScreenCustomizeDarkMode
257261
}
258262

263+
private val _localeChange = Channel<Locale>()
264+
val localChange: Flow<Locale> = _localeChange.receiveAsFlow()
265+
259266
fun currentDestinationIs(route: String): Boolean = controller.currentBackStackEntry?.destination?.route == route
260267

261268
fun <T> getDataFromNextScreen(key: String, defaultValue: T): StateFlow<T>? =
@@ -265,6 +272,12 @@ class WeatherAppState(
265272
controller.currentBackStackEntry?.savedStateHandle?.remove<T>(key)
266273
}
267274

275+
fun onLocaleChange(locale: Locale) {
276+
coroutineScope.launch {
277+
_localeChange.send(locale)
278+
}
279+
}
280+
268281
fun openDrawer() {
269282
coroutineScope.launch {
270283
drawer.open()
@@ -295,7 +308,6 @@ class WeatherAppState(
295308
}
296309
controller.popBackStack(route = popToRoute, inclusive = false)
297310
}
298-
299311
}
300312

301313
fun navigateToCurrentWeather() {

app/src/main/java/com/minhdtm/example/weapose/presentation/ui/home/CurrentWeatherScreen.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import androidx.compose.ui.layout.LastBaseline
2727
import androidx.compose.ui.platform.LocalContext
2828
import androidx.compose.ui.res.painterResource
2929
import androidx.compose.ui.res.stringResource
30+
import androidx.compose.ui.text.style.TextOverflow
3031
import androidx.compose.ui.tooling.preview.Devices.NEXUS_5
3132
import androidx.compose.ui.tooling.preview.Devices.PIXEL_4_XL
3233
import androidx.compose.ui.tooling.preview.Preview
@@ -92,6 +93,13 @@ fun CurrentWeather(
9293
}
9394
}
9495

96+
// Locale change
97+
LaunchedEffect(true) {
98+
appState.localChange.collectLatest {
99+
viewModel.onRefreshCurrentWeather(false)
100+
}
101+
}
102+
95103
// Get event
96104
LaunchedEffect(true) {
97105
viewModel.event.collectLatest { event ->
@@ -339,7 +347,7 @@ fun CurrentWeatherAppBar(
339347
modifier = modifier,
340348
title = {
341349
if (title.isNotBlank()) {
342-
Text(text = title)
350+
Text(text = title, maxLines = 1, overflow = TextOverflow.Visible)
343351
}
344352
},
345353
navigationIcon = {
@@ -370,6 +378,8 @@ fun CurrentWeatherAppBar(
370378
Text(
371379
text = city ?: stringResource(id = R.string.unknown_address),
372380
style = MaterialTheme.typography.titleLarge,
381+
maxLines = 1,
382+
overflow = TextOverflow.Ellipsis,
373383
)
374384
}
375385
}

0 commit comments

Comments
 (0)