Skip to content

Commit

Permalink
Support display cutouts
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbel committed Nov 19, 2023
1 parent bd68da6 commit c7c5d7e
Show file tree
Hide file tree
Showing 14 changed files with 95 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.michaelbel.movies.ui.ktx

import android.content.res.Configuration
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration

val isPortrait: Boolean
@Composable get() {
val configuration = LocalConfiguration.current
return configuration.orientation == Configuration.ORIENTATION_PORTRAIT
}

val displayCutoutWindowInsets: WindowInsets
@Composable get() = if (isPortrait) WindowInsets(0, 0, 0, 0) else WindowInsets.displayCutout
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import org.michaelbel.movies.persistence.database.entity.AccountDb
import org.michaelbel.movies.persistence.database.ktx.orEmpty
import org.michaelbel.movies.ui.compose.AccountAvatar
import org.michaelbel.movies.ui.icons.MoviesIcons
import org.michaelbel.movies.ui.ktx.isPortrait
import org.michaelbel.movies.ui.ktx.lettersTextFontSizeLarge
import org.michaelbel.movies.ui.preview.DevicePreviews
import org.michaelbel.movies.ui.theme.MoviesTheme
Expand Down Expand Up @@ -64,7 +65,7 @@ internal fun AccountScreenContent(
) {
ConstraintLayout(
modifier
.padding(horizontal = 16.dp)
.padding(horizontal = if (isPortrait) 16.dp else 64.dp)
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.primaryContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import org.michaelbel.movies.network.TMDB_TERMS_OF_USE
import org.michaelbel.movies.network.TMDB_URL
import org.michaelbel.movies.ui.icons.MoviesIcons
import org.michaelbel.movies.ui.ktx.clickableWithoutRipple
import org.michaelbel.movies.ui.ktx.isPortrait

@Composable
fun AuthRoute(
Expand Down Expand Up @@ -95,7 +96,7 @@ internal fun AuthScreenContent(

ConstraintLayout(
modifier
.padding(horizontal = 16.dp)
.padding(horizontal = if (isPortrait) 16.dp else 64.dp)
.fillMaxWidth()
.background(
color = MaterialTheme.colorScheme.primaryContainer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.michaelbel.movies.details.ui
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
Expand All @@ -23,6 +24,7 @@ import org.michaelbel.movies.network.connectivity.NetworkStatus
import org.michaelbel.movies.network.connectivity.ktx.isAvailable
import org.michaelbel.movies.network.ktx.isFailure
import org.michaelbel.movies.network.ktx.throwable
import org.michaelbel.movies.ui.ktx.displayCutoutWindowInsets

@Composable
fun DetailsRoute(
Expand Down Expand Up @@ -78,13 +80,15 @@ private fun DetailsScreenContent(
DetailsLoading(
modifier = Modifier
.padding(paddingValues)
.windowInsetsPadding(displayCutoutWindowInsets)
.fillMaxSize()
)
}
is ScreenState.Content<*> -> {
DetailsContent(
modifier = Modifier
.padding(paddingValues)
.windowInsetsPadding(displayCutoutWindowInsets)
.fillMaxSize(),
movie = detailsState.movie,
onNavigateToGallery = onNavigateToGallery
Expand All @@ -94,6 +98,7 @@ private fun DetailsScreenContent(
DetailsFailure(
modifier = Modifier
.padding(paddingValues)
.windowInsetsPadding(displayCutoutWindowInsets)
.fillMaxSize()
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand All @@ -16,6 +17,7 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
import org.michaelbel.movies.ui.icons.MoviesIcons
import org.michaelbel.movies.ui.ktx.displayCutoutWindowInsets
import org.michaelbel.movies.ui.preview.DevicePreviews
import org.michaelbel.movies.ui.preview.provider.TitlePreviewParameterProvider
import org.michaelbel.movies.ui.theme.MoviesTheme
Expand Down Expand Up @@ -43,6 +45,7 @@ fun DetailsToolbar(
actions = {
AnimatedVisibility(
visible = movieUrl != null,
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets),
enter = fadeIn()
) {
if (movieUrl != null) {
Expand All @@ -54,9 +57,8 @@ fun DetailsToolbar(
},
navigationIcon = {
IconButton(
onClick = {
onNavigationIconClick()
}
onClick = { onNavigationIconClick() },
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets)
) {
Image(
imageVector = MoviesIcons.ArrowBack,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
package org.michaelbel.movies.feed.ktx

import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration
import org.michaelbel.movies.ui.ktx.isPortrait

private const val FEED_GRID_PORTRAIT_COLUMNS_COUNT = 2
private const val FEED_GRID_LANDSCAPE_COLUMNS_COUNT = 4

val isPortrait: Boolean
@Composable get() {
val configuration = LocalConfiguration.current
return configuration.orientation == Configuration.ORIENTATION_PORTRAIT
}

val gridColumnsCount: Int
@Composable get() = if (isPortrait) FEED_GRID_PORTRAIT_COLUMNS_COUNT else FEED_GRID_LANDSCAPE_COLUMNS_COUNT
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ import androidx.paging.compose.itemContentType
import androidx.paging.compose.itemKey
import org.michaelbel.movies.common.appearance.FeedView
import org.michaelbel.movies.feed.ktx.gridColumnsCount
import org.michaelbel.movies.feed.ktx.isPortrait
import org.michaelbel.movies.network.isTmdbApiKeyEmpty
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.ui.ktx.isNotEmpty
import org.michaelbel.movies.ui.ktx.isPagingFailure
import org.michaelbel.movies.ui.ktx.isPagingLoading
import org.michaelbel.movies.ui.ktx.isPortrait

@Composable
fun FeedContent(
Expand Down Expand Up @@ -58,7 +58,8 @@ fun FeedContent(
lazyGridState = lazyGridState,
pagingItems = pagingItems,
onMovieClick = onMovieClick,
contentPadding = contentPadding
contentPadding = contentPadding,
modifier = modifier
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import org.michaelbel.movies.common.appearance.FeedView
import org.michaelbel.movies.feed.ktx.gridColumnsCount
import org.michaelbel.movies.feed.ktx.isPortrait
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.ui.ktx.isPortrait
import org.michaelbel.movies.ui.placeholder.PlaceholderHighlight
import org.michaelbel.movies.ui.placeholder.material3.fade
import org.michaelbel.movies.ui.placeholder.placeholder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
Expand Down Expand Up @@ -59,6 +60,7 @@ import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.persistence.database.ktx.orEmpty
import org.michaelbel.movies.ui.compose.NotificationBottomSheet
import org.michaelbel.movies.ui.ktx.clickableWithoutRipple
import org.michaelbel.movies.ui.ktx.displayCutoutWindowInsets
import org.michaelbel.movies.ui.ktx.isFailure
import org.michaelbel.movies.ui.ktx.isLoading
import org.michaelbel.movies.ui.ktx.throwable
Expand Down Expand Up @@ -206,9 +208,7 @@ private fun FeedScreenContent(
topBar = {
FeedToolbar(
title = currentMovieList.titleText,
modifier = Modifier
.fillMaxWidth()
.clickableWithoutRipple { onScrollToTop() },
modifier = Modifier.clickableWithoutRipple { onScrollToTop() },
account = account,
isUpdateIconVisible = isUpdateIconVisible,
onAuthIconClick = {
Expand All @@ -234,14 +234,15 @@ private fun FeedScreenContent(
pagingItems.isLoading -> {
FeedLoading(
feedView = currentFeedView,
modifier = Modifier.fillMaxSize(),
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets),
paddingValues = paddingValues
)
}
pagingItems.isFailure -> {
FeedFailure(
modifier = Modifier
.padding(paddingValues)
.windowInsetsPadding(displayCutoutWindowInsets)
.fillMaxSize()
.clickableWithoutRipple { pagingItems.retry() },
onCheckConnectivityClick = {
Expand All @@ -262,7 +263,7 @@ private fun FeedScreenContent(
pagingItems = pagingItems,
onMovieClick = onNavigateToDetails,
contentPadding = paddingValues,
modifier = Modifier.fillMaxSize()
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.michaelbel.movies.feed.ui

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
Expand All @@ -21,6 +23,7 @@ import org.michaelbel.movies.persistence.database.entity.AccountDb
import org.michaelbel.movies.persistence.database.ktx.isEmpty
import org.michaelbel.movies.ui.compose.AccountAvatar
import org.michaelbel.movies.ui.icons.MoviesIcons
import org.michaelbel.movies.ui.ktx.displayCutoutWindowInsets
import org.michaelbel.movies.ui.ktx.lettersTextFontSizeSmall
import org.michaelbel.movies.ui.preview.DevicePreviews
import org.michaelbel.movies.ui.preview.provider.BooleanPreviewParameterProvider
Expand All @@ -42,6 +45,7 @@ fun FeedToolbar(
title = {
Text(
text = title,
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets),
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = MaterialTheme.typography.titleLarge.copy(
Expand All @@ -51,43 +55,47 @@ fun FeedToolbar(
},
modifier = modifier,
actions = {
if (isUpdateIconVisible) {
Row(
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets)
) {
if (isUpdateIconVisible) {
IconButton(
onClick = onUpdateIconClick
) {
Image(
imageVector = MoviesIcons.SystemUpdate,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimaryContainer)
)
}
}

IconButton(
onClick = onUpdateIconClick
onClick = onSettingsIconClick
) {
Image(
imageVector = MoviesIcons.SystemUpdate,
imageVector = MoviesIcons.Settings,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimaryContainer)
)
}
}

IconButton(
onClick = onSettingsIconClick
) {
Image(
imageVector = MoviesIcons.Settings,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimaryContainer)
)
}

IconButton(
onClick = if (account.isEmpty) onAuthIconClick else onAccountIconClick
) {
if (account.isEmpty) {
Image(
imageVector = MoviesIcons.Account,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimaryContainer)
)
} else {
AccountAvatar(
account = account,
fontSize = account.lettersTextFontSizeSmall,
modifier = Modifier.size(32.dp)
)
IconButton(
onClick = if (account.isEmpty) onAuthIconClick else onAccountIconClick
) {
if (account.isEmpty) {
Image(
imageVector = MoviesIcons.Account,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onPrimaryContainer)
)
} else {
AccountAvatar(
account = account,
fontSize = account.lettersTextFontSizeSmall,
modifier = Modifier.size(32.dp)
)
}
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.PagerDefaults
import androidx.compose.foundation.pager.PagerScope
Expand Down Expand Up @@ -61,6 +62,7 @@ import org.michaelbel.movies.network.isNotOriginal
import org.michaelbel.movies.persistence.database.entity.ImageDb
import org.michaelbel.movies.persistence.database.ktx.original
import org.michaelbel.movies.ui.icons.MoviesIcons
import org.michaelbel.movies.ui.ktx.displayCutoutWindowInsets
import org.michaelbel.movies.work.DownloadImageWorker

@Composable
Expand Down Expand Up @@ -260,7 +262,8 @@ private fun GalleryScreenContent(
enter = fadeIn()
) {
IconButton(
onClick = { onDownloadClick(imageDb) }
onClick = { onDownloadClick(imageDb) },
modifier = Modifier.windowInsetsPadding(displayCutoutWindowInsets)
) {
Image(
imageVector = MoviesIcons.FileDownload,
Expand All @@ -286,6 +289,7 @@ private fun GalleryScreenContent(
top.linkTo(parent.top, 8.dp)
}
.statusBarsPadding()
.windowInsetsPadding(displayCutoutWindowInsets)
) {
Image(
imageVector = MoviesIcons.ArrowBack,
Expand Down
Loading

0 comments on commit c7c5d7e

Please sign in to comment.