fix everything
This commit is contained in:
parent
376f28dc9d
commit
1f245aa337
11 changed files with 139 additions and 137 deletions
|
@ -4,7 +4,7 @@ import retrofit2.http.GET
|
||||||
import retrofit2.http.Query
|
import retrofit2.http.Query
|
||||||
|
|
||||||
interface GeocodingApi {
|
interface GeocodingApi {
|
||||||
@GET("v1/search?count=4")
|
@GET("v1/search?count=10")
|
||||||
suspend fun getGeocodingData(
|
suspend fun getGeocodingData(
|
||||||
@Query("name") location: String,
|
@Query("name") location: String,
|
||||||
): GeocodingDto
|
): GeocodingDto
|
||||||
|
|
|
@ -37,7 +37,11 @@ class QWeatherActivity : ComponentActivity() {
|
||||||
WeatherAppTheme(darkTheme = isDark, monet = prefs.monet) {
|
WeatherAppTheme(darkTheme = isDark, monet = prefs.monet) {
|
||||||
Surface(modifier = Modifier.fillMaxSize()) {
|
Surface(modifier = Modifier.fillMaxSize()) {
|
||||||
Text(text = location.location)
|
Text(text = location.location)
|
||||||
Navigator(screen = if (isLocationSet) MainScreen() else LocationPickerScreen()) {
|
Navigator(
|
||||||
|
screen = if (isLocationSet) MainScreen() else LocationPickerScreen(),
|
||||||
|
onBackPressed = {
|
||||||
|
it !is MainScreen
|
||||||
|
}) {
|
||||||
SlideTransition(it)
|
SlideTransition(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.vectorResource
|
import androidx.compose.ui.res.vectorResource
|
||||||
|
@ -22,7 +21,7 @@ import com.henryhiles.qweather.domain.weather.HourlyWeatherData
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WeatherCard(hour: HourlyWeatherData?, modifier: Modifier = Modifier) {
|
fun WeatherCard(hour: HourlyWeatherData?, location: String, modifier: Modifier = Modifier) {
|
||||||
hour?.let {
|
hour?.let {
|
||||||
val formattedTime = remember(it) {
|
val formattedTime = remember(it) {
|
||||||
it.time.format(DateTimeFormatter.ofPattern("HH:mm"))
|
it.time.format(DateTimeFormatter.ofPattern("HH:mm"))
|
||||||
|
@ -37,10 +36,17 @@ fun WeatherCard(hour: HourlyWeatherData?, modifier: Modifier = Modifier) {
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = location,
|
||||||
|
)
|
||||||
Text(
|
Text(
|
||||||
text = "Today $formattedTime",
|
text = "Today $formattedTime",
|
||||||
modifier = Modifier.align(Alignment.End), color = Color.White
|
|
||||||
)
|
)
|
||||||
|
}
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Image(
|
Image(
|
||||||
painter = painterResource(id = it.weatherType.iconRes),
|
painter = painterResource(id = it.weatherType.iconRes),
|
||||||
|
|
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.henryhiles.qweather.presentation.screenmodel.HourlyWeatherState
|
import com.henryhiles.qweather.presentation.screenmodel.HourlyWeatherState
|
||||||
|
@ -25,7 +24,7 @@ fun WeatherForecast(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 16.dp)
|
.padding(horizontal = 16.dp)
|
||||||
) {
|
) {
|
||||||
Text(text = "Today", fontSize = 20.sp, color = Color.White)
|
Text(text = "Today", fontSize = 20.sp)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
val rowState = rememberLazyListState(LocalDateTime.now().hour)
|
val rowState = rememberLazyListState(LocalDateTime.now().hour)
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material.icons.outlined.MyLocation
|
import androidx.compose.material.icons.outlined.MyLocation
|
||||||
import androidx.compose.material.icons.outlined.Search
|
import androidx.compose.material.icons.outlined.Search
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
|
@ -24,20 +25,35 @@ import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.R
|
||||||
|
import com.henryhiles.qweather.presentation.components.navigation.SmallToolbar
|
||||||
import com.henryhiles.qweather.presentation.screenmodel.LocationPickerScreenModel
|
import com.henryhiles.qweather.presentation.screenmodel.LocationPickerScreenModel
|
||||||
|
|
||||||
|
|
||||||
class LocationPickerScreen : Screen {
|
class LocationPickerScreen : Screen {
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val screenModel: LocationPickerScreenModel = getScreenModel()
|
val screenModel: LocationPickerScreenModel = getScreenModel()
|
||||||
var latitude by remember { mutableStateOf(0f) }
|
var latitude by remember { mutableStateOf(screenModel.prefs.latitude) }
|
||||||
var longitude by remember { mutableStateOf(0f) }
|
var longitude by remember { mutableStateOf(screenModel.prefs.longitude) }
|
||||||
var location by remember { mutableStateOf("") }
|
var location by remember { mutableStateOf(screenModel.prefs.location) }
|
||||||
var locationSearch by remember { mutableStateOf("") }
|
var locationSearch by remember { mutableStateOf("") }
|
||||||
|
var isAboutOpen by remember { mutableStateOf(false) }
|
||||||
val navigator = LocalNavigator.current
|
val navigator = LocalNavigator.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Scaffold(floatingActionButton = {
|
||||||
|
FloatingActionButton(onClick = {
|
||||||
|
screenModel.prefs.location = location
|
||||||
|
screenModel.prefs.latitude = latitude
|
||||||
|
screenModel.prefs.longitude = longitude
|
||||||
|
navigator?.push(MainScreen())
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Check,
|
||||||
|
contentDescription = stringResource(id = R.string.action_apply)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}) {
|
||||||
screenModel.state.error?.let {
|
screenModel.state.error?.let {
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = {},
|
onDismissRequest = {},
|
||||||
|
@ -51,24 +67,31 @@ class LocationPickerScreen : Screen {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
} ?: AlertDialog(
|
} ?: kotlin.run {
|
||||||
onDismissRequest = {},
|
Column {
|
||||||
|
SmallToolbar(
|
||||||
|
title = { Text(text = stringResource(id = R.string.location_choose)) },
|
||||||
|
actions = {
|
||||||
|
IconButton(
|
||||||
|
onClick = { isAboutOpen = true }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Info,
|
||||||
|
contentDescription = stringResource(id = R.string.help_screen)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
if (isAboutOpen) AlertDialog(
|
||||||
|
title = { Text(text = stringResource(id = R.string.location_choose)) },
|
||||||
|
text = { Text(text = stringResource(id = R.string.help_location_picker)) },
|
||||||
|
onDismissRequest = { isAboutOpen = false },
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = { isAboutOpen = false }) {
|
||||||
screenModel.prefs.location = location
|
Text(text = stringResource(id = R.string.action_confirm))
|
||||||
screenModel.prefs.latitude = latitude
|
|
||||||
screenModel.prefs.longitude = longitude
|
|
||||||
navigator?.push(MainScreen())
|
|
||||||
},
|
|
||||||
enabled = location != ""
|
|
||||||
) {
|
|
||||||
Text(text = stringResource(id = R.string.action_apply))
|
|
||||||
}
|
}
|
||||||
},
|
})
|
||||||
title = { Text(text = stringResource(id = R.string.location_choose)) },
|
|
||||||
text = {
|
|
||||||
Column {
|
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
label = { Text(text = stringResource(id = R.string.location)) },
|
label = { Text(text = stringResource(id = R.string.location)) },
|
||||||
keyboardOptions = KeyboardOptions(
|
keyboardOptions = KeyboardOptions(
|
||||||
|
@ -82,9 +105,7 @@ class LocationPickerScreen : Screen {
|
||||||
}),
|
}),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
value = locationSearch,
|
value = locationSearch,
|
||||||
onValueChange = {
|
onValueChange = { locationSearch = it },
|
||||||
locationSearch = it
|
|
||||||
},
|
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
if (locationSearch == "")
|
if (locationSearch == "")
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
|
@ -106,20 +127,17 @@ class LocationPickerScreen : Screen {
|
||||||
contentDescription = stringResource(id = R.string.action_search)
|
contentDescription = stringResource(id = R.string.action_search)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
Text(text = "${screenModel.state.locations != null}")
|
|
||||||
screenModel.state.locations?.let {
|
|
||||||
Text(
|
|
||||||
text = "hi"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (screenModel.state.isLoading) CircularProgressIndicator(
|
if (screenModel.state.isLoading) CircularProgressIndicator(
|
||||||
modifier = Modifier.align(
|
modifier = Modifier
|
||||||
|
.align(
|
||||||
Alignment.CenterHorizontally
|
Alignment.CenterHorizontally
|
||||||
)
|
)
|
||||||
|
.padding(16.dp)
|
||||||
) else screenModel.state.locations?.let {
|
) else screenModel.state.locations?.let {
|
||||||
LazyColumn {
|
LazyColumn {
|
||||||
items(it) {
|
items(it) {
|
||||||
|
@ -161,7 +179,7 @@ class LocationPickerScreen : Screen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package com.henryhiles.qweather.presentation.screenmodel
|
package com.henryhiles.qweather.presentation.screenmodel
|
||||||
|
|
||||||
import android.location.Location
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.coroutineScope
|
||||||
import com.henryhiles.qweather.domain.location.LocationTracker
|
|
||||||
import com.henryhiles.qweather.domain.repository.WeatherRepository
|
import com.henryhiles.qweather.domain.repository.WeatherRepository
|
||||||
import com.henryhiles.qweather.domain.util.Resource
|
import com.henryhiles.qweather.domain.util.Resource
|
||||||
import com.henryhiles.qweather.domain.weather.DailyWeatherData
|
import com.henryhiles.qweather.domain.weather.DailyWeatherData
|
||||||
|
@ -21,21 +19,18 @@ data class DailyWeatherState(
|
||||||
|
|
||||||
class DailyWeatherScreenModel(
|
class DailyWeatherScreenModel(
|
||||||
private val repository: WeatherRepository,
|
private val repository: WeatherRepository,
|
||||||
private val locationTracker: LocationTracker,
|
private val location: LocationPreferenceManager
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
var state by mutableStateOf(DailyWeatherState())
|
var state by mutableStateOf(DailyWeatherState())
|
||||||
private set
|
private set
|
||||||
private var currentLocation: Location? = null
|
|
||||||
|
|
||||||
fun loadWeatherInfo(cache: Boolean = true) {
|
fun loadWeatherInfo(cache: Boolean = true) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
state = state.copy(isLoading = true, error = null)
|
state = state.copy(isLoading = true, error = null)
|
||||||
currentLocation = locationTracker.getCurrentLocation()
|
|
||||||
currentLocation?.let { location ->
|
|
||||||
state = when (val result =
|
state = when (val result =
|
||||||
repository.getDailyWeatherData(
|
repository.getDailyWeatherData(
|
||||||
lat = location.latitude.toFloat(),
|
lat = location.latitude,
|
||||||
long = location.longitude.toFloat(),
|
long = location.longitude,
|
||||||
cache = cache
|
cache = cache
|
||||||
)) {
|
)) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
|
@ -53,12 +48,6 @@ class DailyWeatherScreenModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: kotlin.run {
|
|
||||||
state = state.copy(
|
|
||||||
isLoading = false,
|
|
||||||
error = "Couldn't retrieve location. Make sure to grant permission and enable GPS."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
package com.henryhiles.qweather.presentation.screenmodel
|
package com.henryhiles.qweather.presentation.screenmodel
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import cafe.adriel.voyager.core.model.ScreenModel
|
import cafe.adriel.voyager.core.model.ScreenModel
|
||||||
import cafe.adriel.voyager.core.model.coroutineScope
|
import cafe.adriel.voyager.core.model.coroutineScope
|
||||||
import com.henryhiles.qweather.R
|
|
||||||
import com.henryhiles.qweather.domain.location.LocationTracker
|
|
||||||
import com.henryhiles.qweather.domain.repository.WeatherRepository
|
import com.henryhiles.qweather.domain.repository.WeatherRepository
|
||||||
import com.henryhiles.qweather.domain.util.Resource
|
import com.henryhiles.qweather.domain.util.Resource
|
||||||
import com.henryhiles.qweather.domain.weather.HourlyWeatherInfo
|
import com.henryhiles.qweather.domain.weather.HourlyWeatherInfo
|
||||||
|
@ -22,8 +19,7 @@ data class HourlyWeatherState(
|
||||||
|
|
||||||
class HourlyWeatherScreenModel(
|
class HourlyWeatherScreenModel(
|
||||||
private val repository: WeatherRepository,
|
private val repository: WeatherRepository,
|
||||||
private val locationTracker: LocationTracker,
|
val location: LocationPreferenceManager,
|
||||||
private val context: Context
|
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
var state by mutableStateOf(HourlyWeatherState())
|
var state by mutableStateOf(HourlyWeatherState())
|
||||||
private set
|
private set
|
||||||
|
@ -31,12 +27,10 @@ class HourlyWeatherScreenModel(
|
||||||
fun loadWeatherInfo(cache: Boolean = true) {
|
fun loadWeatherInfo(cache: Boolean = true) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
state = state.copy(isLoading = true, error = null, selected = null)
|
state = state.copy(isLoading = true, error = null, selected = null)
|
||||||
val currentLocation = locationTracker.getCurrentLocation()
|
|
||||||
currentLocation?.let { location ->
|
|
||||||
state = when (val result =
|
state = when (val result =
|
||||||
repository.getHourlyWeatherData(
|
repository.getHourlyWeatherData(
|
||||||
lat = location.latitude.toFloat(),
|
lat = location.latitude,
|
||||||
long = location.longitude.toFloat(),
|
long = location.longitude,
|
||||||
cache = cache
|
cache = cache
|
||||||
)) {
|
)) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
|
@ -55,12 +49,6 @@ class HourlyWeatherScreenModel(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} ?: kotlin.run {
|
|
||||||
state = state.copy(
|
|
||||||
isLoading = false,
|
|
||||||
error = context.getString(R.string.error_location)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.henryhiles.qweather.presentation.tabs
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
import androidx.compose.material.icons.outlined.GpsFixed
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material.icons.outlined.Palette
|
import androidx.compose.material.icons.outlined.Palette
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
@ -19,6 +20,7 @@ import com.henryhiles.qweather.domain.util.NavigationTab
|
||||||
import com.henryhiles.qweather.presentation.components.settings.SettingsCategory
|
import com.henryhiles.qweather.presentation.components.settings.SettingsCategory
|
||||||
import com.henryhiles.qweather.presentation.screen.AboutScreen
|
import com.henryhiles.qweather.presentation.screen.AboutScreen
|
||||||
import com.henryhiles.qweather.presentation.screen.AppearanceSettingsScreen
|
import com.henryhiles.qweather.presentation.screen.AppearanceSettingsScreen
|
||||||
|
import com.henryhiles.qweather.presentation.screen.LocationPickerScreen
|
||||||
|
|
||||||
object SettingsTab : NavigationTab {
|
object SettingsTab : NavigationTab {
|
||||||
override val options: TabOptions
|
override val options: TabOptions
|
||||||
|
@ -45,6 +47,12 @@ object SettingsTab : NavigationTab {
|
||||||
subtext = stringResource(R.string.settings_appearance_description),
|
subtext = stringResource(R.string.settings_appearance_description),
|
||||||
destination = ::AppearanceSettingsScreen
|
destination = ::AppearanceSettingsScreen
|
||||||
)
|
)
|
||||||
|
SettingsCategory(
|
||||||
|
icon = Icons.Outlined.GpsFixed,
|
||||||
|
text = stringResource(R.string.settings_location),
|
||||||
|
subtext = stringResource(R.string.settings_location_description),
|
||||||
|
destination = ::LocationPickerScreen
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.henryhiles.qweather.presentation.tabs
|
package com.henryhiles.qweather.presentation.tabs
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
@ -17,8 +16,6 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.R
|
||||||
import com.henryhiles.qweather.domain.util.NavigationTab
|
import com.henryhiles.qweather.domain.util.NavigationTab
|
||||||
import com.henryhiles.qweather.presentation.components.weather.WeatherCard
|
import com.henryhiles.qweather.presentation.components.weather.WeatherCard
|
||||||
|
@ -41,18 +38,12 @@ object TodayTab : NavigationTab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalPermissionsApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val weatherViewModel = getScreenModel<HourlyWeatherScreenModel>()
|
val weatherViewModel = getScreenModel<HourlyWeatherScreenModel>()
|
||||||
val permissionsState = rememberPermissionState(
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
) {
|
|
||||||
weatherViewModel.loadWeatherInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(key1 = true) {
|
LaunchedEffect(key1 = false) {
|
||||||
permissionsState.launchPermissionRequest()
|
weatherViewModel.loadWeatherInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
|
@ -90,7 +81,8 @@ object TodayTab : NavigationTab {
|
||||||
WeatherCard(
|
WeatherCard(
|
||||||
hour = weatherViewModel.state.selected?.let {
|
hour = weatherViewModel.state.selected?.let {
|
||||||
weatherViewModel.state.hourlyWeatherInfo?.weatherData?.get(it)
|
weatherViewModel.state.hourlyWeatherInfo?.weatherData?.get(it)
|
||||||
} ?: weatherViewModel.state.hourlyWeatherInfo?.currentWeatherData
|
} ?: weatherViewModel.state.hourlyWeatherInfo?.currentWeatherData,
|
||||||
|
location = weatherViewModel.location.location
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
WeatherForecast(
|
WeatherForecast(
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.henryhiles.qweather.presentation.tabs
|
package com.henryhiles.qweather.presentation.tabs
|
||||||
|
|
||||||
import android.Manifest
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||||
|
@ -9,15 +9,15 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.DateRange
|
import androidx.compose.material.icons.filled.DateRange
|
||||||
import androidx.compose.material.icons.filled.Refresh
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.R
|
||||||
import com.henryhiles.qweather.domain.util.NavigationTab
|
import com.henryhiles.qweather.domain.util.NavigationTab
|
||||||
import com.henryhiles.qweather.presentation.components.weather.WeatherDay
|
import com.henryhiles.qweather.presentation.components.weather.WeatherDay
|
||||||
|
@ -39,21 +39,14 @@ object WeekTab : NavigationTab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalPermissionsApi::class)
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val weatherViewModel = getScreenModel<DailyWeatherScreenModel>()
|
val weatherViewModel = getScreenModel<DailyWeatherScreenModel>()
|
||||||
|
|
||||||
val permissionsState = rememberPermissionState(
|
LaunchedEffect(key1 = false) {
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
) {
|
|
||||||
weatherViewModel.loadWeatherInfo()
|
weatherViewModel.loadWeatherInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(key1 = true) {
|
|
||||||
permissionsState.launchPermissionRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
Box(modifier = Modifier.fillMaxSize()) {
|
Box(modifier = Modifier.fillMaxSize()) {
|
||||||
when {
|
when {
|
||||||
weatherViewModel.state.isLoading -> {
|
weatherViewModel.state.isLoading -> {
|
||||||
|
|
|
@ -12,14 +12,19 @@
|
||||||
<string name="action_reload">Reload</string>
|
<string name="action_reload">Reload</string>
|
||||||
<string name="action_try_again">Try Again</string>
|
<string name="action_try_again">Try Again</string>
|
||||||
|
|
||||||
<string name="selected">Selected</string>
|
<string name="selected">Selected</string>x
|
||||||
|
|
||||||
|
<string name="help_screen">How do I use this screen?</string>
|
||||||
|
<string name="help_location_picker">Please either tap the auto-pick button or enter a location. Then tap the apply button in the bottom left corner.</string>
|
||||||
|
|
||||||
<string name="appearance_theme">Theme</string>
|
<string name="appearance_theme">Theme</string>
|
||||||
<string name="appearance_monet">Dynamic Theme</string>
|
<string name="appearance_monet">Dynamic Theme</string>
|
||||||
<string name="appearance_monet_description">Available on Android 12+</string>
|
<string name="appearance_monet_description">Available on Android 12+</string>
|
||||||
|
|
||||||
<string name="settings_appearance">Appearance</string>
|
<string name="settings_appearance">Appearance</string>
|
||||||
<string name="settings_appearance_description">Theme, code style</string>
|
<string name="settings_appearance_description">Theme, dynamic colors</string>
|
||||||
|
<string name="settings_location">Location</string>
|
||||||
|
<string name="settings_location_description">Location to fetch data from</string>
|
||||||
|
|
||||||
<string name="location">Location</string>
|
<string name="location">Location</string>
|
||||||
<string name="location_string">%1$s, %2$s, %3$s</string>
|
<string name="location_string">%1$s, %2$s, %3$s</string>
|
||||||
|
|
Reference in a new issue