Skip to content
This repository was archived by the owner on Aug 21, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions design/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ android {

dependencies {
implementation(libs.androidx.material3)
implementation(libs.androidx.core.ktx)

testImplementation(libs.junit)
testImplementation(project(":testUtils"))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gravatar.app.design.components

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.platform.LocalView
import androidx.core.view.WindowCompat

@Composable
fun Screen(
appearanceLightStatusBars: Boolean = !isSystemInDarkTheme(),
content: @Composable () -> Unit,
) {
val view = LocalView.current
SideEffect {
val window = (view.context as? android.app.Activity)?.window
val controller = window?.let { WindowCompat.getInsetsController(it, view) }
controller?.isAppearanceLightStatusBars = appearanceLightStatusBars
}
content()
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.gravatar.app.homeUi.presentation.home.components

import android.os.Build
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.BlurredEdgeTreatment
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.blur
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
Expand All @@ -27,8 +27,14 @@ internal fun BlurredHeaderBackground(
Box(
modifier = Modifier
.matchParentSize()
.background(Color.Black.copy(alpha = 0.15f))
.background(Color.Black.copy(alpha = scrimAlpha))
)
content()
}
}

private val scrimAlpha = if (Build.VERSION.SDK_INT >= 32) {
0.15f
} else {
0.6f
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,15 @@ internal fun TopBarPickerPopup(
}
}

TopBarPickerPopup(
anchorAlignment = anchorAlignment,
offset = offset,
onAboutAppClicked = onAboutAppClicked,
onDismissRequest = onDismissRequest,
onEvent = viewModel::onEvent
)
GravatarTheme {
TopBarPickerPopup(
anchorAlignment = anchorAlignment,
offset = offset,
onAboutAppClicked = onAboutAppClicked,
onDismissRequest = onDismissRequest,
onEvent = viewModel::onEvent
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
import com.gravatar.app.design.components.Screen
import com.gravatar.app.design.components.snackbar.SnackbarType
import com.gravatar.app.design.components.snackbar.showGravatarSnackbar
import com.gravatar.app.design.theme.GravatarAppTheme
Expand Down Expand Up @@ -139,17 +140,21 @@ internal fun GravatarScreen(
}
}

GravatarScreen(
uiState = uiState,
onEvent = viewModel::onEvent,
onTakePictureClicked = takePhotoCallback,
onPickMediaClicked = {
if (!mediaPickerLaunched) {
pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
mediaPickerLaunched = true
}
},
)
Screen(
appearanceLightStatusBars = false
) {
GravatarScreen(
uiState = uiState,
onEvent = viewModel::onEvent,
onTakePictureClicked = takePhotoCallback,
onPickMediaClicked = {
if (!mediaPickerLaunched) {
pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
mediaPickerLaunched = true
}
},
)
}
}

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.constraintlayout.compose.ExperimentalMotionApi
import androidx.constraintlayout.compose.MotionLayout
import androidx.constraintlayout.compose.MotionScene
import androidx.constraintlayout.compose.layoutId
import com.gravatar.app.design.theme.GravatarAppTheme
import com.gravatar.app.homeUi.R
import com.gravatar.app.homeUi.presentation.home.components.BlurredHeaderBackground
import com.gravatar.app.homeUi.presentation.home.components.GravatarAvatarWithShadow
Expand Down Expand Up @@ -59,56 +60,58 @@ internal fun GravatarHeader(
.decodeToString()
}

BlurredHeaderBackground(
avatarUrl = avatarUrl,
modifier = modifier.fillMaxWidth(),
) {
MotionLayout(
motionScene = MotionScene(content = motionScene),
progress = progress,
modifier = modifier
.systemBarsPadding()
.fillMaxWidth()
.height(expandedHeight)
GravatarAppTheme(darkTheme = true) {
BlurredHeaderBackground(
avatarUrl = avatarUrl,
modifier = modifier.fillMaxWidth(),
) {
// Main circular avatar
GravatarAvatarWithShadow(
url = avatarUrl,
borderShape = CircleShape,
modifier = Modifier
.layoutId("avatar1")
)

// Secondary square avatar
GravatarAvatarWithShadow(
url = avatarUrl,
borderShape = RoundedCornerShape(8.dp),
modifier = Modifier
.layoutId("avatar2")
)

// Menu button
IconButton(
onClick = {
topBarMenuVisible = true
},
modifier = Modifier
.layoutId("menuButton")
MotionLayout(
motionScene = MotionScene(content = motionScene),
progress = progress,
modifier = modifier
.systemBarsPadding()
.fillMaxWidth()
.height(expandedHeight)
) {
Image(
painter = painterResource(id = R.drawable.more_button),
contentDescription = stringResource(R.string.gravatar_tab_header_more_options),
// Main circular avatar
GravatarAvatarWithShadow(
url = avatarUrl,
borderShape = CircleShape,
modifier = Modifier
.layoutId("avatar1")
)
}

Box(modifier = Modifier.layoutId("menuPopup")) {
if (topBarMenuVisible) {
TopBarPickerPopup(
anchorAlignment = Alignment.End,
onDismissRequest = { topBarMenuVisible = false },
onAboutAppClicked = onAboutAppClicked
// Secondary square avatar
GravatarAvatarWithShadow(
url = avatarUrl,
borderShape = RoundedCornerShape(8.dp),
modifier = Modifier
.layoutId("avatar2")
)

// Menu button
IconButton(
onClick = {
topBarMenuVisible = true
},
modifier = Modifier
.layoutId("menuButton")
) {
Image(
painter = painterResource(id = R.drawable.more_button),
contentDescription = stringResource(R.string.gravatar_tab_header_more_options),
)
}

Box(modifier = Modifier.layoutId("menuPopup")) {
if (topBarMenuVisible) {
TopBarPickerPopup(
anchorAlignment = Alignment.End,
onDismissRequest = { topBarMenuVisible = false },
onAboutAppClicked = onAboutAppClicked
)
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
import com.gravatar.app.design.components.Screen
import com.gravatar.app.design.components.snackbar.SnackbarType
import com.gravatar.app.design.components.snackbar.showGravatarSnackbar
import com.gravatar.app.homeUi.R
Expand Down Expand Up @@ -79,12 +80,16 @@ internal fun ProfileScreen(
}
}

ProfileScreen(
uiState = uiState,
onEvent = { event ->
viewModel.onEvent(profileEvent = event)
}
)
Screen(
appearanceLightStatusBars = false
) {
ProfileScreen(
uiState = uiState,
onEvent = { event ->
viewModel.onEvent(profileEvent = event)
}
)
}
}

@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.repeatOnLifecycle
import com.gravatar.app.design.components.Screen
import com.gravatar.app.design.theme.GravatarAppTheme
import com.gravatar.app.homeUi.GravatarFileProvider
import com.gravatar.app.homeUi.presentation.home.components.topbar.components.about.AboutAppDialog
Expand Down Expand Up @@ -73,12 +74,16 @@ internal fun ShareScreen(
}
}

ShareScreen(
uiState = uiState,
onEvent = { event ->
viewModel.onEvent(event)
}
)
Screen(
appearanceLightStatusBars = false
) {
ShareScreen(
uiState = uiState,
onEvent = { event ->
viewModel.onEvent(event)
}
)
}
}

@Composable
Expand Down
Loading