Skip to content

Commit

Permalink
Merge pull request #172 from hossain-khan/126-dynamic-dimension
Browse files Browse the repository at this point in the history
[ADDED] Support for dynamic padding using `WindowSizeClass`.
  • Loading branch information
hossain-khan authored Jan 18, 2025
2 parents 5380793 + ee60d64 commit 3af7628
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 16 deletions.
5 changes: 4 additions & 1 deletion app/src/main/java/dev/hossain/weatheralert/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
import com.slack.circuit.backstack.rememberSaveableBackStack
import com.slack.circuit.foundation.Circuit
import com.slack.circuit.foundation.CircuitCompositionLocals
Expand All @@ -17,6 +18,7 @@ import dev.hossain.weatheralert.di.AppScope
import dev.hossain.weatheralert.network.NetworkMonitor
import dev.hossain.weatheralert.ui.alertslist.CurrentWeatherAlertScreen
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions
import javax.inject.Inject

@ContributesMultibinding(AppScope::class, boundType = Activity::class)
Expand All @@ -32,7 +34,8 @@ class MainActivity
enableEdgeToEdge()

setContent {
WeatherAlertAppTheme {
val windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
WeatherAlertAppTheme(dimensions = windowSizeClass.windowWidthSizeClass.dimensions()) {
// See https://slackhq.github.io/circuit/navigation/
val backStack = rememberSaveableBackStack(root = CurrentWeatherAlertScreen("root"))
val navigator = rememberCircuitNavigator(backStack)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import dev.hossain.weatheralert.di.AppScope
import dev.hossain.weatheralert.ui.addapikey.BringYourOwnApiKeyScreen
import dev.hossain.weatheralert.ui.serviceConfig
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions
import dev.hossain.weatheralert.util.Analytics
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -376,7 +377,7 @@ fun AddNewWeatherAlertScreen(
modifier
.fillMaxSize()
.padding(contentPaddingValues)
.padding(horizontal = 24.dp)
.padding(horizontal = MaterialTheme.dimensions.horizontalScreenPadding)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(24.dp),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ import dev.hossain.weatheralert.ui.WeatherServiceLogoConfig
import dev.hossain.weatheralert.ui.alertslist.CurrentWeatherAlertScreen
import dev.hossain.weatheralert.ui.serviceConfig
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions
import dev.hossain.weatheralert.util.Analytics
import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize
Expand Down Expand Up @@ -271,7 +272,7 @@ fun BringYourOwnApiKeyScreen(
modifier
.fillMaxSize()
.padding(contentPaddingValues)
.padding(horizontal = 24.dp)
.padding(horizontal = MaterialTheme.dimensions.horizontalScreenPadding)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(24.dp),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import dev.hossain.weatheralert.network.NetworkMonitor
import dev.hossain.weatheralert.ui.addalert.AddNewWeatherAlertScreen
import dev.hossain.weatheralert.ui.details.WeatherAlertDetailsScreen
import dev.hossain.weatheralert.ui.settings.UserSettingsScreen
import dev.hossain.weatheralert.ui.theme.dimensions
import dev.hossain.weatheralert.util.Analytics
import dev.hossain.weatheralert.util.formatUnit
import dev.hossain.weatheralert.util.parseMarkdown
Expand Down Expand Up @@ -377,7 +378,11 @@ fun AlertTileGrid(
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(vertical = 12.dp, horizontal = 16.dp),
contentPadding =
PaddingValues(
vertical = MaterialTheme.dimensions.verticalScreenPadding,
horizontal = MaterialTheme.dimensions.horizontalScreenPadding,
),
) {
itemsIndexed(
items = tiles,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import dev.hossain.weatheralert.R
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions

@Composable
fun EmptyAlertState(modifier: Modifier = Modifier) {
Expand All @@ -31,7 +32,7 @@ fun EmptyAlertState(modifier: Modifier = Modifier) {
modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(horizontal = 24.dp),
.padding(horizontal = MaterialTheme.dimensions.horizontalScreenPadding),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Expand Down Expand Up @@ -78,7 +79,11 @@ fun EmptyAlertState(modifier: Modifier = Modifier) {
.alpha(0.9f),
contentDescription = "Tomorrow.io Logo",
)
Image(

// Open-Mateo is disabled due to some inconsistencies discovered
// See https://github.com/hossain-khan/android-weather-alert/pull/165

/*Image(
painter = painterResource(id = R.drawable.open_mateo_logo),
modifier =
Modifier
Expand All @@ -89,7 +94,7 @@ fun EmptyAlertState(modifier: Modifier = Modifier) {
// Reduces intensity by a bit
.alpha(0.9f),
contentDescription = "Tomorrow.io Logo",
)
)*/
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import dev.hossain.weatheralert.db.UserCityAlert
import dev.hossain.weatheralert.di.AppScope
import dev.hossain.weatheralert.ui.serviceConfig
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions
import dev.hossain.weatheralert.util.Analytics
import dev.hossain.weatheralert.util.formatToDate
import dev.hossain.weatheralert.util.formatUnit
Expand Down Expand Up @@ -211,7 +212,7 @@ fun WeatherAlertDetailsScreen(
modifier
.fillMaxSize()
.padding(contentPaddingValues)
.padding(horizontal = 24.dp)
.padding(horizontal = MaterialTheme.dimensions.horizontalScreenPadding)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import dev.hossain.weatheralert.di.AppScope
import dev.hossain.weatheralert.ui.addapikey.BringYourOwnApiKeyScreen
import dev.hossain.weatheralert.ui.serviceConfig
import dev.hossain.weatheralert.ui.theme.WeatherAlertAppTheme
import dev.hossain.weatheralert.ui.theme.dimensions
import dev.hossain.weatheralert.util.Analytics
import dev.hossain.weatheralert.work.scheduleWeatherAlertsWork
import dev.hossain.weatheralert.work.supportedWeatherUpdateInterval
Expand Down Expand Up @@ -190,13 +191,13 @@ fun UserSettingsScreen(
},
)
},
) { padding ->
) { contentPaddingValues ->
Column(
modifier =
modifier
.fillMaxSize()
.padding(padding)
.padding(horizontal = 16.dp)
.padding(contentPaddingValues)
.padding(horizontal = MaterialTheme.dimensions.horizontalScreenPadding)
.verticalScroll(rememberScrollState()),
verticalArrangement = Arrangement.spacedBy(16.dp),
) {
Expand Down
86 changes: 86 additions & 0 deletions app/src/main/java/dev/hossain/weatheralert/ui/theme/Dimension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package dev.hossain.weatheralert.ui.theme

import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.window.core.layout.WindowWidthSizeClass

// For background, see:
// - https://github.com/hossain-khan/android-weather-alert/issues/126
// - https://bsky.app/profile/hossain.dev/post/3lflhafgn622p

/**
* Data class to hold dimension values for padding and screen spacing.
*/
data class Dimensions(
val smallPadding: Dp,
val mediumPadding: Dp,
val largePadding: Dp,
val horizontalScreenPadding: Dp,
val verticalScreenPadding: Dp,
)

/**
* CompositionLocal to provide the current Dimensions instance.
*/
val LocalDimensions =
staticCompositionLocalOf {
Dimensions(
smallPadding = 16.dp,
mediumPadding = 24.dp,
largePadding = 32.dp,
horizontalScreenPadding = 16.dp,
verticalScreenPadding = 16.dp,
)
}

/**
* Extension property to access the current Dimensions instance from MaterialTheme.
*/
val MaterialTheme.dimensions: Dimensions
@Composable
get() = LocalDimensions.current

/**
* Extension function to get Dimensions based on the WindowWidthSizeClass.
*
* @receiver WindowWidthSizeClass The current window size class.
* @return Dimensions The corresponding Dimensions instance.
*/
internal fun WindowWidthSizeClass.dimensions(): Dimensions =
when (this) {
WindowWidthSizeClass.COMPACT ->
Dimensions(
smallPadding = 8.dp,
mediumPadding = 16.dp,
largePadding = 24.dp,
horizontalScreenPadding = 16.dp,
verticalScreenPadding = 16.dp,
)
WindowWidthSizeClass.MEDIUM ->
Dimensions(
smallPadding = 16.dp,
mediumPadding = 24.dp,
largePadding = 32.dp,
horizontalScreenPadding = 48.dp,
verticalScreenPadding = 24.dp,
)
WindowWidthSizeClass.EXPANDED ->
Dimensions(
smallPadding = 24.dp,
mediumPadding = 32.dp,
largePadding = 40.dp,
horizontalScreenPadding = 64.dp,
verticalScreenPadding = 24.dp,
)
else ->
Dimensions(
smallPadding = 16.dp,
mediumPadding = 24.dp,
largePadding = 32.dp,
horizontalScreenPadding = 16.dp,
verticalScreenPadding = 16.dp,
)
}
18 changes: 13 additions & 5 deletions app/src/main/java/dev/hossain/weatheralert/ui/theme/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalContext

private val DarkColorScheme =
Expand Down Expand Up @@ -34,6 +35,7 @@ fun WeatherAlertAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = true,
dimensions: Dimensions = LocalDimensions.current,
content: @Composable () -> Unit,
) {
val colorScheme =
Expand All @@ -47,9 +49,15 @@ fun WeatherAlertAppTheme(
else -> LightColorScheme
}

MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
content = content,
)
// CompositionLocalProvider binds values to ProvidableCompositionLocal keys.
// https://developer.android.com/develop/ui/compose/compositionlocal
CompositionLocalProvider(
LocalDimensions provides dimensions,
) {
MaterialTheme(
colorScheme = colorScheme,
typography = AppTypography,
content = content,
)
}
}

0 comments on commit 3af7628

Please sign in to comment.