@@ -3,6 +3,14 @@ package xyz.flipchat.app.features.profile
33import android.app.Activity
44import android.content.Context
55import android.os.Parcelable
6+ import androidx.compose.animation.AnimatedVisibility
7+ import androidx.compose.animation.Crossfade
8+ import androidx.compose.animation.core.tween
9+ import androidx.compose.animation.fadeIn
10+ import androidx.compose.animation.fadeOut
11+ import androidx.compose.animation.shrinkVertically
12+ import androidx.compose.animation.slideInVertically
13+ import androidx.compose.animation.slideOutVertically
614import androidx.compose.foundation.Image
715import androidx.compose.foundation.layout.Column
816import androidx.compose.foundation.layout.Spacer
@@ -184,86 +192,128 @@ private fun ProfileContent(
184192 }
185193 )
186194
187- if (state.linkedSocialProfile == null ) {
188- Text (
189- text = state.displayName,
190- style = CodeTheme .typography.textLarge,
191- color = CodeTheme .colors.textMain
192- )
193- if (state.canConnectAccount && state.isSelf) {
194- val xOAuthLauncher = rememberLauncherForOAuth(OAuthProvider .X ) { accessToken ->
195- println (" x access token=$accessToken " )
196- dispatchEvent(ProfileViewModel .Event .LinkXAccount (accessToken))
197- }
195+ // Crossfade between no-account and linked-account states
196+ Crossfade (
197+ targetState = state.linkedSocialProfile != null ,
198+ animationSpec = tween(durationMillis = 300 )
199+ ) { isLinked ->
200+ if (! isLinked) {
201+ // No account linked
202+ Column (horizontalAlignment = Alignment .CenterHorizontally ) {
203+ Text (
204+ text = state.displayName,
205+ style = CodeTheme .typography.textLarge,
206+ color = CodeTheme .colors.textMain
207+ )
208+ if (state.canConnectAccount && state.isSelf) {
209+ val xOAuthLauncher = rememberLauncherForOAuth(OAuthProvider .X ) { accessToken ->
210+ println (" x access token=$accessToken " )
211+ dispatchEvent(ProfileViewModel .Event .LinkXAccount (accessToken))
212+ }
198213
199- CodeButton (
200- modifier = Modifier .fillMaxWidth()
201- .padding(top = CodeTheme .dimens.grid.x12)
202- .padding(horizontal = CodeTheme .dimens.inset),
203- buttonState = ButtonState .Filled ,
204- onClick = { xOAuthLauncher.launch(OAuthProvider .X .launchIntent(context)) },
205- content = {
206- Image (
207- painter = rememberVectorPainter(image = ImageVector .vectorResource(id = R .drawable.ic_twitter_x)),
208- colorFilter = ColorFilter .tint(Color .Black ),
209- contentDescription = null
210- )
211- Spacer (Modifier .width(CodeTheme .dimens.grid.x2))
212- Text (
213- text = stringResource(R .string.action_connectYourAccount),
214- )
214+ AnimatedVisibility (
215+ visible = true ,
216+ enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
217+ exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
218+ ) {
219+ CodeButton (
220+ modifier = Modifier
221+ .fillMaxWidth()
222+ .padding(top = CodeTheme .dimens.grid.x12)
223+ .padding(horizontal = CodeTheme .dimens.inset),
224+ buttonState = ButtonState .Filled ,
225+ onClick = { xOAuthLauncher.launch(OAuthProvider .X .launchIntent(context)) },
226+ content = {
227+ Image (
228+ painter = rememberVectorPainter(image = ImageVector .vectorResource(id = R .drawable.ic_twitter_x)),
229+ colorFilter = ColorFilter .tint(Color .Black ),
230+ contentDescription = null
231+ )
232+ Spacer (Modifier .width(CodeTheme .dimens.grid.x2))
233+ Text (
234+ text = stringResource(R .string.action_connectYourAccount),
235+ )
236+ }
237+ )
238+ }
215239 }
216- )
217- }
218- } else {
219- SocialUserDisplay (
220- modifier = Modifier .fillMaxWidth(),
221- profile = state.linkedSocialProfile
222- )
240+ }
241+ } else {
242+ // Linked account state
243+ state.linkedSocialProfile?.let { linkedProfile ->
244+ Column (horizontalAlignment = Alignment .CenterHorizontally ) {
245+ SocialUserDisplay (
246+ modifier = Modifier .fillMaxWidth(),
247+ profile = linkedProfile
248+ )
223249
224- state.username?.let { username ->
225- Text (
226- modifier = Modifier .fillMaxWidth(),
227- text = username,
228- style = CodeTheme .typography.textSmall,
229- color = CodeTheme .colors.textSecondary,
230- textAlign = TextAlign .Center
231- )
232- }
250+ state.username?.let { username ->
251+ AnimatedVisibility (
252+ visible = true ,
253+ enter = fadeIn(),
254+ exit = fadeOut() + shrinkVertically()
255+ ) {
256+ Text (
257+ modifier = Modifier .fillMaxWidth(),
258+ text = username,
259+ style = CodeTheme .typography.textSmall,
260+ color = CodeTheme .colors.textSecondary,
261+ textAlign = TextAlign .Center
262+ )
263+ }
264+ }
233265
234- when (state.linkedSocialProfile) {
235- is SocialProfile .Unknown -> Unit
236- is SocialProfile .X -> {
237- Text (
238- modifier = Modifier
239- .fillMaxWidth()
240- .padding(top = CodeTheme .dimens.grid.x8),
241- text = " ${state.linkedSocialProfile.followerCountFormatted} Followers" ,
242- style = CodeTheme .typography.textSmall,
243- color = CodeTheme .colors.textSecondary,
244- textAlign = TextAlign .Center
245- )
246- Text (
247- modifier = Modifier
248- .fillMaxWidth(0.70f )
249- .padding(top = CodeTheme .dimens.grid.x1),
250- text = state.linkedSocialProfile.description,
251- style = CodeTheme .typography.textSmall,
252- color = CodeTheme .colors.textSecondary,
253- textAlign = TextAlign .Center ,
254- )
255- }
256- }
266+ when (linkedProfile) {
267+ is SocialProfile .Unknown -> Unit
268+ is SocialProfile .X -> {
269+ AnimatedVisibility (
270+ visible = true ,
271+ enter = fadeIn(),
272+ exit = fadeOut() + shrinkVertically()
273+ ) {
274+ Column (horizontalAlignment = Alignment .CenterHorizontally ) {
275+ Text (
276+ modifier = Modifier
277+ .fillMaxWidth()
278+ .padding(top = CodeTheme .dimens.grid.x8),
279+ text = " ${linkedProfile.followerCountFormatted} Followers" ,
280+ style = CodeTheme .typography.textSmall,
281+ color = CodeTheme .colors.textSecondary,
282+ textAlign = TextAlign .Center
283+ )
284+ Text (
285+ modifier = Modifier
286+ .fillMaxWidth(0.70f )
287+ .padding(top = CodeTheme .dimens.grid.x1),
288+ text = linkedProfile.description,
289+ style = CodeTheme .typography.textSmall,
290+ color = CodeTheme .colors.textSecondary,
291+ textAlign = TextAlign .Center ,
292+ )
293+ }
294+ }
295+ }
296+ }
257297
258- if (! isInTab) {
259- CodeButton (
260- modifier = Modifier .fillMaxWidth()
261- .padding(top = CodeTheme .dimens.grid.x12)
262- .padding(horizontal = CodeTheme .dimens.inset),
263- buttonState = ButtonState .Filled ,
264- onClick = { uriHandler.openUri(state.linkedSocialProfile.profileUrl) },
265- text = stringResource(R .string.action_openProfileOnPlatform, state.linkedSocialProfile.platformTypeName)
266- )
298+ if (! isInTab) {
299+ AnimatedVisibility (
300+ visible = true ,
301+ enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
302+ exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
303+ ) {
304+ CodeButton (
305+ modifier = Modifier
306+ .fillMaxWidth()
307+ .padding(top = CodeTheme .dimens.grid.x12)
308+ .padding(horizontal = CodeTheme .dimens.inset),
309+ buttonState = ButtonState .Filled ,
310+ onClick = { uriHandler.openUri(linkedProfile.profileUrl) },
311+ text = stringResource(R .string.action_openProfileOnPlatform, linkedProfile.platformTypeName)
312+ )
313+ }
314+ }
315+ }
316+ }
267317 }
268318 }
269319 }
0 commit comments