Skip to content

Commit

Permalink
Merge pull request #6 from bachhoan88/feature_weathers
Browse files Browse the repository at this point in the history
Update weather by days
  • Loading branch information
hoaibn-0332 authored Dec 14, 2021
2 parents 5a1d941 + d68756f commit 4f16289
Show file tree
Hide file tree
Showing 11 changed files with 385 additions and 92 deletions.
12 changes: 1 addition & 11 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,6 @@ android {
vectorDrawables {
useSupportLibrary true
}

javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.incremental" : "true",
"room.expandProjection" : "true",
"room.schemaLocation" : "$projectDir/schemas".toString(),
"dagger.gradle.incremental" : "true"
]
}
}
}

flavorDimensions "environment"
Expand Down Expand Up @@ -137,6 +126,7 @@ dependencies {

implementation Libs.AndroidX.Room.runtime
implementation Libs.AndroidX.Room.ktx
testImplementation Libs.Coroutines.test

kapt Libs.AndroidX.Room.compiler
}
3 changes: 2 additions & 1 deletion app/src/dev/res/values/config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
<resources>
<string name="base_url">https://api.openweathermap.org/data/2.5/</string>
<string name="com.crashlytics.android.build_id">RANDOM_UUID</string>
<string name="weather_app_id">WEATHER_APP_ID</string>
<!-- <string name="weather_app_id">WEATHER_APP_ID</string>-->
<string name="weather_app_id">19db43609e401fea86cc6f8d7e2bc8cd</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,52 @@ import com.example.weather.domain.usecase.UseCase
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import java.util.*
import javax.inject.Inject

class GetHourlyWeatherUseCase @Inject constructor(
private val weatherRepository: WeatherRepository,
@ApplicationContext private val context: Context
) : UseCase<GetHourlyWeatherUseCase.Params, List<Hourly>>() {
) : UseCase<GetHourlyWeatherUseCase.Params, GetHourlyWeatherUseCase.Response>() {

override fun execute(params: Params?): Flow<List<Hourly>> {
override fun execute(params: Params?): Flow<Response> {
if (params != null) {
return weatherRepository
.getHourlyWeather(params.lat, params.long)
.map { it.drop(1) }
.map { it.take(MAX_WEATHERS_ON_DAY) }
.map { hourly ->
Response(
today = hourly.filter { it.dt <= maxToday() },
tomorrow = hourly.filter { it.dt > maxToday() && it.dt <= maxTomorrow() }
)
}
}

return BaseException.AlertException(-1, context.getString(R.string.lat_lon_invalid)).asFlow()
}

private fun maxToday(): Long {
val calendar = Calendar.getInstance(TimeZone.getDefault())
calendar.add(Calendar.DATE, 1)
calendar.set(Calendar.HOUR_OF_DAY, 6)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
return calendar.timeInMillis / 1000L
}

private fun maxTomorrow(): Long {
val calendar = Calendar.getInstance(TimeZone.getDefault())
calendar.add(Calendar.DATE, 2)
calendar.set(Calendar.HOUR_OF_DAY, 6)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
return calendar.timeInMillis / 1000L
}

data class Params(val lat: Double, val long: Double)

data class Response(val today: List<Hourly>, val tomorrow: List<Hourly>)

companion object {
private const val MAX_WEATHERS_ON_DAY = 20
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import com.example.weather.presentation.ui.home.HomeScreen

@Composable
fun WeatherApp(appState: WeatherAppState = rememberWeatherAppState()) {
val todayLazyListState = rememberLazyListState()
val tomorrowLazyListState = rememberLazyListState()

NavHost(
navController = appState.controller,
startDestination = Screen.Home.route
Expand All @@ -19,8 +22,10 @@ fun WeatherApp(appState: WeatherAppState = rememberWeatherAppState()) {
HomeScreen(
viewModel = hiltViewModel(),
navigateToNextSevenDay = { lat, long ->
appState.navigateToSevenDays(lat, long)
}
appState.navigateToSevenDays(lat.toFloat(), long.toFloat())
},
todayLazyListState = todayLazyListState,
tomorrowLazyListState = tomorrowLazyListState
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.example.weather.presentation.ui

import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController

Expand All @@ -19,6 +21,20 @@ fun rememberWeatherAppState(
WeatherAppState(controller)
}

@Composable
fun rememberLazyListState(
vararg inputs: Any?,
initialFirstVisibleItemIndex: Int = 0,
initialFirstVisibleItemScrollOffset: Int = 0
): LazyListState {
return rememberSaveable(inputs, saver = LazyListState.Saver) {
LazyListState(
initialFirstVisibleItemIndex,
initialFirstVisibleItemScrollOffset
)
}
}

class WeatherAppState(val controller: NavHostController) {
fun navigateToSevenDays(lat: Float, long: Float) {
controller.navigate(Screen.NextSevenDays.createRoute(lat, long))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
package com.example.weather.presentation.ui.day

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Search
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.weather.R
import com.example.weather.presentation.ui.custom.BackgroundImage
import com.google.accompanist.insets.statusBarsPadding

@Composable
fun SevenDaysScreen(
Expand All @@ -10,4 +28,80 @@ fun SevenDaysScreen(
long: Double = 105.8412,
onBackPressed: () -> Unit
) {
val scaffoldState = rememberScaffoldState()

SevenDaysScreenContent(
modifier = Modifier.statusBarsPadding(),
onBackPressed = onBackPressed,
scaffoldState = scaffoldState
)
}

@Composable
fun SevenDaysScreenContent(
modifier: Modifier,
scaffoldState: ScaffoldState = rememberScaffoldState(),
onBackPressed: (() -> Unit)? = null,
) {
val drawableId = if (isSystemInDarkTheme()) R.drawable.background_night else R.drawable.background

Surface(modifier = Modifier.fillMaxSize()) {
BackgroundImage(
modifier = Modifier.fillMaxSize(),
painter = painterResource(drawableId),
alignment = Alignment.TopCenter
) {
Scaffold(
scaffoldState = scaffoldState,
topBar = {
SevenDaysTopAppBar { onBackPressed?.invoke() }
},
modifier = modifier,
backgroundColor = Color.Transparent
) {
val contentModifier = Modifier
.fillMaxSize()
.padding(all = 18.dp)
}
}
}
}

@Composable
private fun SevenDaysTopAppBar(
elevation: Dp = 0.dp,
onBackPressed: (() -> Unit)? = null,
) {
TopAppBar(
title = {
Text(
text = stringResource(R.string.app_name),
modifier = Modifier
.fillMaxSize()
.padding(bottom = 4.dp, top = 12.dp),
style = MaterialTheme.typography.h6.copy(color = MaterialTheme.colors.onPrimary),
textAlign = TextAlign.Center
)
},
navigationIcon = {
IconButton(onClick = { onBackPressed?.invoke() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = stringResource(R.string.close),
tint = MaterialTheme.colors.primary
)
}
},
actions = {
IconButton(onClick = { /** Not implement */ }) {
Icon(
imageVector = Icons.Filled.Search,
contentDescription = stringResource(R.string.search_city),
tint = MaterialTheme.colors.primary
)
}
},
backgroundColor = Color.Transparent,
elevation = elevation
)
}
Loading

0 comments on commit 4f16289

Please sign in to comment.