Skip to content

Commit

Permalink
Added shared element transition between contact row and chat screen
Browse files Browse the repository at this point in the history
  • Loading branch information
DAGalpin committed May 30, 2024
1 parent a2e6278 commit 4e19716
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 208 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import com.google.android.samples.socialite.ui.Bubble
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class BubbleActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down
38 changes: 25 additions & 13 deletions app/src/main/java/com/google/android/samples/socialite/ui/Bubble.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,37 @@

package com.google.android.samples.socialite.ui

import androidx.compose.animation.AnimatedContent
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.google.android.samples.socialite.ui.chat.ChatScreen

@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun Bubble(chatId: Long) {
SocialTheme {
ChatScreen(
chatId = chatId,
foreground = false,
onBackPressed = null,
// TODO (donovanfm): Hook up camera button in the Bubble composable
onCameraClick = {},
// TODO (jolandaverhoef): Hook up play video button in the Bubble composable
onVideoClick = {},
// TODO (mayurikhin): Hook up camera button in the Bubble composable
onPhotoPickerClick = {},
modifier = Modifier.fillMaxSize(),
)
SharedTransitionLayout {
AnimatedContent(targetState = 1) { _ ->
SocialTheme {
ChatScreen(
chatId = chatId,
foreground = false,
onBackPressed = null,
// TODO (donovanfm): Hook up camera button in the Bubble composable
onCameraClick = {},
// TODO (jolandaverhoef): Hook up play video button in the Bubble composable
onVideoClick = {},
// TODO (mayurikhin): Hook up camera button in the Bubble composable
onPhotoPickerClick = {},
modifier = Modifier.fillMaxSize(),
sharedTransitionScope = this@SharedTransitionLayout,
animatedContentScope = this@AnimatedContent
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

package com.google.android.samples.socialite.ui

import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand All @@ -40,60 +45,81 @@ import androidx.compose.ui.unit.sp
import com.google.android.samples.socialite.data.utils.toReadableString
import com.google.android.samples.socialite.model.ChatDetail

@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun ChatRow(
chat: ChatDetail,
onClick: (() -> Unit)?,
modifier: Modifier = Modifier,
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope
) {
Row(
modifier = modifier
.fillMaxWidth()
.then(
if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier,
)
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
// This only supports DM for now.
val contact = chat.attendees.first()
Image(
painter = rememberIconPainter(contentUri = contact.iconUri),
contentDescription = null,
modifier = Modifier
.size(48.dp)
.clip(CircleShape)
.background(Color.LightGray),
)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.Start,
) {
Text(
text = contact.name,
style = MaterialTheme.typography.bodyLarge,
fontSize = 16.sp,
)
Text(
text = chat.chatWithLastMessage.text,
style = MaterialTheme.typography.bodySmall,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp),
fontWeight = FontWeight.Light,
fontSize = 14.sp,
)
}
Column(
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally,
with(sharedTransitionScope) {
Row(
modifier = modifier
.fillMaxWidth()
.then(
if (onClick != null) Modifier.clickable(onClick = onClick) else Modifier,
)
.padding(16.dp)
.sharedBounds(
sharedTransitionScope.rememberSharedContentState(key = "Bounds${chat.chatWithLastMessage.id}"),
animatedVisibilityScope = animatedContentScope,
enter = fadeIn(),
exit = fadeOut(),
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp),
) {
Text(
text = chat.chatWithLastMessage.timestamp.toReadableString(),
fontSize = 14.sp,
// This only supports DM for now.
val contact = chat.attendees.first()
Image(
painter = rememberIconPainter(contentUri = contact.iconUri),
contentDescription = null,
modifier = Modifier.Companion
.sharedElement(
sharedTransitionScope.rememberSharedContentState(key = chat.chatWithLastMessage.id),
animatedVisibilityScope = animatedContentScope
)
.size(48.dp)
.clip(CircleShape)
.background(Color.LightGray),
)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.Start,
) {
Text(
text = contact.name,
style = MaterialTheme.typography.bodyLarge,
fontSize = 16.sp,
modifier = Modifier.Companion.sharedBounds(
sharedTransitionScope.rememberSharedContentState(key = "Text${chat.chatWithLastMessage.id}"),
animatedVisibilityScope = animatedContentScope,
enter = fadeIn(),
exit = fadeOut(),
)
)
Text(
text = chat.chatWithLastMessage.text,
style = MaterialTheme.typography.bodySmall,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp),
fontWeight = FontWeight.Light,
fontSize = 14.sp,
)
}
Column(
verticalArrangement = Arrangement.SpaceEvenly,
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = chat.chatWithLastMessage.timestamp.toReadableString(),
fontSize = 14.sp,
)
}
}
}
}
Loading

0 comments on commit 4e19716

Please sign in to comment.