add reload capabi lities among other things
This commit is contained in:
parent
49f7f4bd9a
commit
ff7710143b
17 changed files with 189 additions and 139 deletions
|
@ -12,23 +12,6 @@ import retrofit2.Retrofit
|
||||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
import retrofit2.create
|
import retrofit2.create
|
||||||
|
|
||||||
//@Module
|
|
||||||
//@InstallIn(SingletonComponent::class)
|
|
||||||
//object AppModule {
|
|
||||||
// @Provides
|
|
||||||
// @Singleton
|
|
||||||
// fun provideWeatherApi(): WeatherApi {
|
|
||||||
// return Retrofit.Builder().baseUrl("https://api.open-meteo.com")
|
|
||||||
// .addConverterFactory(MoshiConverterFactory.create()).build().create()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Provides
|
|
||||||
// @Singleton
|
|
||||||
// fun provideFusedLocationProviderClient(app: Application): FusedLocationProviderClient {
|
|
||||||
// return LocationServices.getFusedLocationProviderClient(app)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
val appModule = module {
|
val appModule = module {
|
||||||
fun provideWeatherApi(): WeatherApi {
|
fun provideWeatherApi(): WeatherApi {
|
||||||
return Retrofit.Builder().baseUrl("https://api.open-meteo.com")
|
return Retrofit.Builder().baseUrl("https://api.open-meteo.com")
|
||||||
|
|
|
@ -4,15 +4,6 @@ import com.henryhiles.qweather.domain.location.LocationTracker
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
//@Module
|
|
||||||
//@InstallIn(SingletonComponent::class)
|
|
||||||
//abstract class LocationModule {
|
|
||||||
// @Binds
|
|
||||||
// @Singleton
|
|
||||||
// abstract fun bindLocationTracker(defaultLocationTracker: DefaultLocationTracker): LocationTracker
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
val locationModule = module {
|
val locationModule = module {
|
||||||
singleOf(::LocationTracker)
|
singleOf(::LocationTracker)
|
||||||
}
|
}
|
|
@ -4,14 +4,6 @@ import com.henryhiles.qweather.domain.repository.WeatherRepository
|
||||||
import org.koin.core.module.dsl.singleOf
|
import org.koin.core.module.dsl.singleOf
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
|
|
||||||
//@Module
|
|
||||||
//@InstallIn(SingletonComponent::class)
|
|
||||||
//abstract class RepositoryModule {
|
|
||||||
// @Binds
|
|
||||||
// @Singleton
|
|
||||||
// abstract fun bindWeatherRepository(weatherRepository: WeatherRepository): WeatherRepository
|
|
||||||
//}
|
|
||||||
|
|
||||||
val repositoryModule = module {
|
val repositoryModule = module {
|
||||||
singleOf(::WeatherRepository)
|
singleOf(::WeatherRepository)
|
||||||
}
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.henryhiles.qweather.domain.util
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import cafe.adriel.voyager.navigator.tab.Tab
|
||||||
|
|
||||||
|
interface NavigationTab : Tab {
|
||||||
|
@Composable
|
||||||
|
fun Actions()
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.henryhiles.qweather.presentation.components
|
package com.henryhiles.qweather.presentation.components.navigation
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.henryhiles.qweather.presentation.components.navigation
|
||||||
|
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.DateRange
|
||||||
|
import androidx.compose.material.icons.filled.Home
|
||||||
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.NavigationBar
|
||||||
|
import androidx.compose.material3.NavigationBarItem
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||||
|
import com.henryhiles.qweather.R
|
||||||
|
import com.henryhiles.qweather.presentation.tabs.SettingsTab
|
||||||
|
import com.henryhiles.qweather.presentation.tabs.TodayTab
|
||||||
|
import com.henryhiles.qweather.presentation.tabs.WeekTab
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BottomBar(navigator: TabNavigator) {
|
||||||
|
NavigationBar {
|
||||||
|
NavigationBarItem(
|
||||||
|
selected = navigator.current == TodayTab,
|
||||||
|
onClick = { navigator.current = TodayTab },
|
||||||
|
label = { Text(text = stringResource(id = R.string.tab_today)) },
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Home,
|
||||||
|
contentDescription = stringResource(id = R.string.tab_today)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
NavigationBarItem(
|
||||||
|
selected = navigator.current == WeekTab,
|
||||||
|
onClick = { navigator.current = WeekTab },
|
||||||
|
label = { Text(text = "Weekly") },
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.DateRange,
|
||||||
|
contentDescription = "Weekly"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
NavigationBarItem(
|
||||||
|
selected = navigator.current == SettingsTab,
|
||||||
|
onClick = { navigator.current = SettingsTab },
|
||||||
|
label = { Text(text = "Settings") },
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Settings,
|
||||||
|
contentDescription = "Settings"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.henryhiles.qweather.presentation.components
|
package com.henryhiles.qweather.presentation.components.navigation
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
|
@ -7,12 +7,13 @@ import androidx.compose.runtime.Composable
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
fun LargeToolbar(
|
fun LargeToolbar(
|
||||||
title: String,
|
title: @Composable () -> Unit,
|
||||||
actions: @Composable RowScope.() -> Unit = {},
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
|
backButton: Boolean = false
|
||||||
) {
|
) {
|
||||||
LargeTopAppBar(
|
LargeTopAppBar(
|
||||||
title = { Text(text = title) },
|
title = title,
|
||||||
navigationIcon = { BackButton() },
|
navigationIcon = { if (backButton) BackButton() },
|
||||||
actions = actions,
|
actions = actions,
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.henryhiles.qweather.presentation.components
|
package com.henryhiles.qweather.presentation.components.navigation
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
|
@ -7,12 +7,13 @@ import androidx.compose.runtime.Composable
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
fun SmallToolbar(
|
fun SmallToolbar(
|
||||||
title: String,
|
title: @Composable () -> Unit,
|
||||||
actions: @Composable RowScope.() -> Unit = {},
|
actions: @Composable RowScope.() -> Unit = {},
|
||||||
|
backButton: Boolean = true
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(text = title) },
|
title = title,
|
||||||
navigationIcon = { BackButton() },
|
navigationIcon = { if (backButton) BackButton() },
|
||||||
actions = actions,
|
actions = actions,
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
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.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
|
||||||
|
@ -17,7 +18,7 @@ import java.time.format.DateTimeFormatter
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WeatherDay(dailyWeatherData: DailyWeatherData) {
|
fun WeatherDay(dailyWeatherData: DailyWeatherData) {
|
||||||
val formattedDate = remember {
|
val formattedDate by remember {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
dailyWeatherData.date.format(
|
dailyWeatherData.date.format(
|
||||||
DateTimeFormatter.ofPattern("E d")
|
DateTimeFormatter.ofPattern("E d")
|
||||||
|
@ -45,7 +46,7 @@ fun WeatherDay(dailyWeatherData: DailyWeatherData) {
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
Column {
|
Column {
|
||||||
Text(
|
Text(
|
||||||
text = formattedDate.value
|
text = formattedDate
|
||||||
)
|
)
|
||||||
Text(text = "Feels like ${dailyWeatherData.apparentTemperatureMax}°C")
|
Text(text = "Feels like ${dailyWeatherData.apparentTemperatureMax}°C")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.henryhiles.qweather.presentation.screen
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
|
import com.henryhiles.qweather.presentation.components.navigation.LargeToolbar
|
||||||
|
|
||||||
|
class AboutScreen : Screen {
|
||||||
|
@Composable
|
||||||
|
override fun Content() {
|
||||||
|
Scaffold(topBar = { LargeToolbar(title = { Text(text = "About") }, backButton = true) }) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(it)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
|
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.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
@ -13,7 +14,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.koin.getScreenModel
|
import cafe.adriel.voyager.koin.getScreenModel
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.R
|
||||||
import com.henryhiles.qweather.presentation.components.LargeToolbar
|
import com.henryhiles.qweather.presentation.components.navigation.SmallToolbar
|
||||||
import com.henryhiles.qweather.presentation.components.settings.SettingsItemChoice
|
import com.henryhiles.qweather.presentation.components.settings.SettingsItemChoice
|
||||||
import com.henryhiles.qweather.presentation.components.settings.SettingsSwitch
|
import com.henryhiles.qweather.presentation.components.settings.SettingsSwitch
|
||||||
import com.henryhiles.qweather.presentation.screenmodel.AppearancePreferencesScreenModel
|
import com.henryhiles.qweather.presentation.screenmodel.AppearancePreferencesScreenModel
|
||||||
|
@ -24,12 +25,16 @@ class AppearanceSettingsScreen : Screen {
|
||||||
override fun Content() = Screen()
|
override fun Content() = Screen()
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Screen(
|
private fun Screen() {
|
||||||
screenModel: AppearancePreferencesScreenModel = getScreenModel()
|
val screenModel: AppearancePreferencesScreenModel = getScreenModel()
|
||||||
) {
|
|
||||||
val ctx = LocalContext.current
|
val ctx = LocalContext.current
|
||||||
|
|
||||||
Scaffold(topBar = { Toolbar() }) { padding ->
|
Scaffold(topBar = {
|
||||||
|
SmallToolbar(
|
||||||
|
title = { Text(text = stringResource(R.string.settings_appearance)) },
|
||||||
|
backButton = true
|
||||||
|
)
|
||||||
|
}) { padding ->
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(padding)
|
.padding(padding)
|
||||||
|
@ -52,13 +57,4 @@ class AppearanceSettingsScreen : Screen {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun Toolbar(
|
|
||||||
) {
|
|
||||||
LargeToolbar(
|
|
||||||
title = stringResource(R.string.settings_appearance),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,60 +2,33 @@ package com.henryhiles.qweather.presentation.screen
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material.icons.filled.DateRange
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material.icons.filled.Home
|
|
||||||
import androidx.compose.material.icons.filled.Settings
|
|
||||||
import androidx.compose.material3.*
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import cafe.adriel.voyager.core.screen.Screen
|
import cafe.adriel.voyager.core.screen.Screen
|
||||||
import cafe.adriel.voyager.navigator.CurrentScreen
|
import cafe.adriel.voyager.navigator.CurrentScreen
|
||||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.domain.util.NavigationTab
|
||||||
import com.henryhiles.qweather.presentation.tabs.SettingsTab
|
import com.henryhiles.qweather.presentation.components.navigation.BottomBar
|
||||||
|
import com.henryhiles.qweather.presentation.components.navigation.SmallToolbar
|
||||||
import com.henryhiles.qweather.presentation.tabs.TodayTab
|
import com.henryhiles.qweather.presentation.tabs.TodayTab
|
||||||
import com.henryhiles.qweather.presentation.tabs.WeekTab
|
|
||||||
|
|
||||||
class MainScreen : Screen {
|
class MainScreen : Screen {
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
TabNavigator(tab = TodayTab) { navigator ->
|
TabNavigator(tab = TodayTab) {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
|
topBar = {
|
||||||
|
SmallToolbar(
|
||||||
|
title = { Text(text = "QWeather") },
|
||||||
|
actions = {
|
||||||
|
(it.current as? NavigationTab)?.Actions()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
NavigationBar {
|
BottomBar(navigator = it)
|
||||||
NavigationBarItem(
|
|
||||||
selected = navigator.current == TodayTab,
|
|
||||||
onClick = { navigator.current = TodayTab },
|
|
||||||
label = { Text(text = stringResource(id = R.string.tab_today)) },
|
|
||||||
icon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Home,
|
|
||||||
contentDescription = stringResource(id = R.string.tab_today)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
NavigationBarItem(
|
|
||||||
selected = navigator.current == WeekTab,
|
|
||||||
onClick = { navigator.current = WeekTab },
|
|
||||||
label = { Text(text = "Weekly") },
|
|
||||||
icon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.DateRange,
|
|
||||||
contentDescription = "Weekly"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
NavigationBarItem(
|
|
||||||
selected = navigator.current == SettingsTab,
|
|
||||||
onClick = { navigator.current = SettingsTab },
|
|
||||||
label = { Text(text = "Settings") },
|
|
||||||
icon = {
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Settings,
|
|
||||||
contentDescription = "Settings"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
) { padding ->
|
) { padding ->
|
||||||
Box(modifier = Modifier.padding(padding)) {
|
Box(modifier = Modifier.padding(padding)) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
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
|
||||||
|
@ -23,11 +24,12 @@ class DailyWeatherScreenModel constructor(
|
||||||
) : ScreenModel {
|
) : ScreenModel {
|
||||||
var state by mutableStateOf(DailyWeatherState())
|
var state by mutableStateOf(DailyWeatherState())
|
||||||
private set
|
private set
|
||||||
|
private var currentLocation: Location? = null
|
||||||
|
|
||||||
fun loadWeatherInfo() {
|
fun loadWeatherInfo() {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
state = state.copy(isLoading = true, error = null)
|
state = state.copy(isLoading = true, error = null)
|
||||||
val currentLocation = locationTracker.getCurrentLocation()
|
currentLocation = locationTracker.getCurrentLocation()
|
||||||
currentLocation?.let { location ->
|
currentLocation?.let { location ->
|
||||||
state = when (val result =
|
state = when (val result =
|
||||||
repository.getDailyWeatherData(location.latitude, location.longitude)) {
|
repository.getDailyWeatherData(location.latitude, location.longitude)) {
|
||||||
|
@ -38,7 +40,6 @@ class DailyWeatherScreenModel constructor(
|
||||||
error = null
|
error = null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
is Resource.Error -> {
|
is Resource.Error -> {
|
||||||
state.copy(
|
state.copy(
|
||||||
dailyWeatherData = null,
|
dailyWeatherData = null,
|
||||||
|
|
|
@ -1,26 +1,26 @@
|
||||||
package com.henryhiles.qweather.presentation.tabs
|
package com.henryhiles.qweather.presentation.tabs
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
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.Info
|
||||||
import androidx.compose.material.icons.outlined.Palette
|
import androidx.compose.material.icons.outlined.Palette
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
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.navigator.tab.Tab
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
import cafe.adriel.voyager.navigator.tab.TabOptions
|
import cafe.adriel.voyager.navigator.tab.TabOptions
|
||||||
import com.henryhiles.qweather.R
|
import com.henryhiles.qweather.R
|
||||||
import com.henryhiles.qweather.presentation.components.SmallToolbar
|
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.AppearanceSettingsScreen
|
import com.henryhiles.qweather.presentation.screen.AppearanceSettingsScreen
|
||||||
|
|
||||||
object SettingsTab : Tab {
|
object SettingsTab : NavigationTab {
|
||||||
override val options: TabOptions
|
override val options: TabOptions
|
||||||
@Composable
|
@Composable
|
||||||
get() {
|
get() {
|
||||||
|
@ -38,26 +38,25 @@ object SettingsTab : Tab {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
Scaffold(
|
Column {
|
||||||
topBar = {
|
SettingsCategory(
|
||||||
SmallToolbar(
|
icon = Icons.Outlined.Palette,
|
||||||
title = stringResource(R.string.tab_settings),
|
text = stringResource(R.string.settings_appearance),
|
||||||
)
|
subtext = stringResource(R.string.settings_appearance_description),
|
||||||
},
|
destination = ::AppearanceSettingsScreen
|
||||||
) {
|
)
|
||||||
Column(
|
}
|
||||||
modifier = Modifier
|
}
|
||||||
.padding(it)
|
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
|
||||||
|
|
||||||
SettingsCategory(
|
@Composable
|
||||||
icon = Icons.Outlined.Palette,
|
override fun Actions() {
|
||||||
text = stringResource(R.string.settings_appearance),
|
val navigator = LocalNavigator.currentOrThrow.parent
|
||||||
subtext = stringResource(R.string.settings_appearance_description),
|
|
||||||
destination = ::AppearanceSettingsScreen
|
IconButton(onClick = { navigator?.push(AboutScreen()) }) {
|
||||||
)
|
Icon(
|
||||||
}
|
imageVector = Icons.Outlined.Info,
|
||||||
|
contentDescription = stringResource(R.string.action_open_about)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,10 +5,8 @@ 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
|
||||||
import androidx.compose.material.icons.filled.Home
|
import androidx.compose.material.icons.filled.Home
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
@ -18,16 +16,16 @@ import androidx.compose.ui.graphics.vector.rememberVectorPainter
|
||||||
import androidx.compose.ui.res.stringResource
|
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.Tab
|
|
||||||
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.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
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.presentation.components.weather.WeatherCard
|
import com.henryhiles.qweather.presentation.components.weather.WeatherCard
|
||||||
import com.henryhiles.qweather.presentation.components.weather.WeatherForecast
|
import com.henryhiles.qweather.presentation.components.weather.WeatherForecast
|
||||||
import com.henryhiles.qweather.presentation.screenmodel.HourlyWeatherScreenModel
|
import com.henryhiles.qweather.presentation.screenmodel.HourlyWeatherScreenModel
|
||||||
|
|
||||||
object TodayTab : Tab {
|
object TodayTab : NavigationTab {
|
||||||
override val options: TabOptions
|
override val options: TabOptions
|
||||||
@Composable
|
@Composable
|
||||||
get() {
|
get() {
|
||||||
|
@ -43,7 +41,7 @@ object TodayTab : Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalPermissionsApi::class)
|
@OptIn(ExperimentalPermissionsApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
val weatherViewModel = getScreenModel<HourlyWeatherScreenModel>()
|
val weatherViewModel = getScreenModel<HourlyWeatherScreenModel>()
|
||||||
|
@ -92,4 +90,16 @@ object TodayTab : Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun Actions() {
|
||||||
|
val viewModel: HourlyWeatherScreenModel = getScreenModel()
|
||||||
|
|
||||||
|
IconButton(onClick = { viewModel.loadWeatherInfo() }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.Refresh,
|
||||||
|
contentDescription = stringResource(R.string.action_reload)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import androidx.compose.foundation.lazy.items
|
||||||
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.DateRange
|
import androidx.compose.material.icons.filled.DateRange
|
||||||
|
import androidx.compose.material.icons.filled.Refresh
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
@ -16,15 +17,15 @@ 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.Tab
|
|
||||||
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.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.rememberPermissionState
|
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.presentation.components.weather.WeatherDay
|
import com.henryhiles.qweather.presentation.components.weather.WeatherDay
|
||||||
import com.henryhiles.qweather.presentation.screenmodel.DailyWeatherScreenModel
|
import com.henryhiles.qweather.presentation.screenmodel.DailyWeatherScreenModel
|
||||||
|
|
||||||
object WeekTab : Tab {
|
object WeekTab : NavigationTab {
|
||||||
override val options: TabOptions
|
override val options: TabOptions
|
||||||
@Composable
|
@Composable
|
||||||
get() {
|
get() {
|
||||||
|
@ -92,4 +93,16 @@ object WeekTab : Tab {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
override fun Actions() {
|
||||||
|
val viewModel: DailyWeatherScreenModel = getScreenModel()
|
||||||
|
|
||||||
|
IconButton(onClick = { viewModel.loadWeatherInfo() }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.Refresh,
|
||||||
|
contentDescription = stringResource(R.string.action_reload)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
<string name="action_back">Back</string>
|
<string name="action_back">Back</string>
|
||||||
<string name="action_confirm">Confirm</string>
|
<string name="action_confirm">Confirm</string>
|
||||||
|
<string name="action_open_about">About</string>
|
||||||
|
<string name="action_reload">Reload</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>
|
||||||
|
|
Reference in a new issue