@@ -14,6 +14,7 @@ import androidx.compose.animation.slideOutVertically
1414import androidx.compose.foundation.Image
1515import androidx.compose.foundation.layout.Column
1616import androidx.compose.foundation.layout.Spacer
17+ import androidx.compose.foundation.layout.fillMaxSize
1718import androidx.compose.foundation.layout.fillMaxWidth
1819import androidx.compose.foundation.layout.padding
1920import androidx.compose.foundation.layout.size
@@ -43,6 +44,8 @@ import androidx.compose.ui.unit.dp
4344import androidx.lifecycle.Lifecycle
4445import cafe.adriel.voyager.core.registry.ScreenRegistry
4546import cafe.adriel.voyager.core.screen.Screen
47+ import cafe.adriel.voyager.core.screen.ScreenKey
48+ import cafe.adriel.voyager.core.screen.uniqueScreenKey
4649import cafe.adriel.voyager.hilt.getViewModel
4750import com.getcode.manager.BottomBarManager
4851import com.getcode.model.ID
@@ -74,6 +77,9 @@ import xyz.flipchat.services.internal.data.mapper.nullIfEmpty
7477
7578@Parcelize
7679class ProfileScreen (val userId : ID ? = null , val isInTab : Boolean ) : Screen, Parcelable {
80+
81+ override val key: ScreenKey = uniqueScreenKey
82+
7783 @Composable
7884 override fun Content () {
7985 val navigator = LocalCodeNavigator .current
@@ -200,19 +206,32 @@ private fun ProfileContent(
200206 }
201207 )
202208
203- // Crossfade between no-account and linked-account states
204- Crossfade (
205- targetState = state.linkedSocialProfile != null ,
206- animationSpec = tween(durationMillis = 300 )
207- ) { isLinked ->
208- if (! isLinked) {
209- // No account linked
210- Column (horizontalAlignment = Alignment .CenterHorizontally ) {
211- Text (
212- text = state.displayName,
213- style = CodeTheme .typography.textLarge,
214- color = CodeTheme .colors.textMain
215- )
209+ // SocialUserDisplay (title with platform logo)
210+ if (state.linkedSocialProfile != null ) {
211+ SocialUserDisplay (
212+ modifier = Modifier .fillMaxWidth(),
213+ profile = state.linkedSocialProfile
214+ )
215+ } else {
216+ Text (
217+ text = state.displayName,
218+ style = CodeTheme .typography.textLarge,
219+ color = CodeTheme .colors.textMain,
220+ textAlign = TextAlign .Center
221+ )
222+ }
223+
224+ Column (
225+ modifier = Modifier .fillMaxWidth(),
226+ horizontalAlignment = Alignment .CenterHorizontally
227+ ) {
228+ // Crossfade for linked vs unlinked content
229+ Crossfade (
230+ targetState = state.linkedSocialProfile != null ,
231+ animationSpec = tween(durationMillis = 300 )
232+ ) { isLinked ->
233+ if (! isLinked) {
234+ // Unlinked state
216235 if (state.canConnectAccount && state.isSelf) {
217236 val xOAuthLauncher = rememberLauncherForOAuth(OAuthProvider .X ) { accessToken ->
218237 println (" x access token=$accessToken " )
@@ -238,92 +257,219 @@ private fun ProfileContent(
238257 contentDescription = null
239258 )
240259 Spacer (Modifier .width(CodeTheme .dimens.grid.x2))
241- Text (
242- text = stringResource(R .string.action_connectYourAccount),
243- )
260+ Text (text = stringResource(R .string.action_connectYourAccount))
244261 }
245262 )
246263 }
247264 }
248- }
249- } else {
250- // Linked account state
251- state.linkedSocialProfile?.let { linkedProfile ->
252- Column (horizontalAlignment = Alignment .CenterHorizontally ) {
253- SocialUserDisplay (
254- modifier = Modifier .fillMaxWidth(),
255- profile = linkedProfile
256- )
257-
258- state.username?.let { username ->
259- AnimatedVisibility (
260- visible = true ,
261- enter = fadeIn(),
262- exit = fadeOut() + shrinkVertically()
263- ) {
264- Text (
265- modifier = Modifier .fillMaxWidth(),
266- text = username,
267- style = CodeTheme .typography.textSmall,
268- color = CodeTheme .colors.textSecondary,
269- textAlign = TextAlign .Center
270- )
271- }
272- }
273-
274- when (linkedProfile) {
275- is SocialProfile .Unknown -> Unit
276- is SocialProfile .X -> {
265+ } else {
266+ // Linked state
267+ state.linkedSocialProfile?.let { linkedProfile ->
268+ Column (
269+ horizontalAlignment = Alignment .CenterHorizontally
270+ ) {
271+ state.username?.let { username ->
277272 AnimatedVisibility (
278273 visible = true ,
279274 enter = fadeIn(),
280275 exit = fadeOut() + shrinkVertically()
281276 ) {
282- Column (horizontalAlignment = Alignment .CenterHorizontally ) {
283- Text (
284- modifier = Modifier
285- .fillMaxWidth()
286- .padding(top = CodeTheme .dimens.grid.x8),
287- text = " ${linkedProfile.followerCountFormatted} Followers" ,
288- style = CodeTheme .typography.textSmall,
289- color = CodeTheme .colors.textSecondary,
290- textAlign = TextAlign .Center
291- )
292- Text (
293- modifier = Modifier
294- .fillMaxWidth(0.70f )
295- .padding(top = CodeTheme .dimens.grid.x1),
296- text = linkedProfile.description,
297- style = CodeTheme .typography.textSmall,
298- color = CodeTheme .colors.textSecondary,
299- textAlign = TextAlign .Center ,
300- )
277+ Text (
278+ modifier = Modifier .fillMaxWidth(),
279+ text = username,
280+ style = CodeTheme .typography.textSmall,
281+ color = CodeTheme .colors.textSecondary,
282+ textAlign = TextAlign .Center
283+ )
284+ }
285+ }
286+
287+ when (linkedProfile) {
288+ is SocialProfile .X -> {
289+ AnimatedVisibility (
290+ visible = true ,
291+ enter = fadeIn(),
292+ exit = fadeOut() + shrinkVertically()
293+ ) {
294+ Column (horizontalAlignment = Alignment .CenterHorizontally ) {
295+ Text (
296+ modifier = Modifier
297+ .fillMaxWidth()
298+ .padding(top = CodeTheme .dimens.grid.x8),
299+ text = " ${linkedProfile.followerCountFormatted} Followers" ,
300+ style = CodeTheme .typography.textSmall,
301+ color = CodeTheme .colors.textSecondary,
302+ textAlign = TextAlign .Center
303+ )
304+ Text (
305+ modifier = Modifier
306+ .fillMaxWidth(0.70f )
307+ .padding(top = CodeTheme .dimens.grid.x1),
308+ text = linkedProfile.description,
309+ style = CodeTheme .typography.textSmall,
310+ color = CodeTheme .colors.textSecondary,
311+ textAlign = TextAlign .Center
312+ )
313+ }
301314 }
302315 }
316+ is SocialProfile .Unknown -> Unit
303317 }
304- }
305318
306- if (! isInTab) {
307- AnimatedVisibility (
308- visible = true ,
309- enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
310- exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
311- ) {
312- CodeButton (
313- modifier = Modifier
314- .fillMaxWidth()
315- .padding(top = CodeTheme .dimens.grid.x12)
316- .padding(horizontal = CodeTheme .dimens.inset),
317- buttonState = ButtonState .Filled ,
318- onClick = { uriHandler.openUri(linkedProfile.profileUrl) },
319- text = stringResource(R .string.action_openProfileOnPlatform, linkedProfile.platformTypeName)
320- )
319+ if (! isInTab) {
320+ AnimatedVisibility (
321+ visible = true ,
322+ enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
323+ exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
324+ ) {
325+ CodeButton (
326+ modifier = Modifier
327+ .fillMaxWidth()
328+ .padding(top = CodeTheme .dimens.grid.x12)
329+ .padding(horizontal = CodeTheme .dimens.inset),
330+ buttonState = ButtonState .Filled ,
331+ onClick = { uriHandler.openUri(linkedProfile.profileUrl) },
332+ text = stringResource(R .string.action_openProfileOnPlatform, linkedProfile.platformTypeName)
333+ )
334+ }
321335 }
322336 }
323337 }
324338 }
325339 }
326340 }
341+
342+ // // Crossfade between no-account and linked-account states
343+ // Crossfade(
344+ // modifier = Modifier.fillMaxSize(),
345+ // targetState = state.linkedSocialProfile != null,
346+ // animationSpec = tween(durationMillis = 300)
347+ // ) { isLinked ->
348+ // if (!isLinked) {
349+ // // No account linked
350+ // Column(
351+ // modifier = Modifier.fillMaxSize(),
352+ // horizontalAlignment = Alignment.CenterHorizontally
353+ // ) {
354+ // Text(
355+ // text = state.displayName,
356+ // style = CodeTheme.typography.textLarge,
357+ // color = CodeTheme.colors.textMain
358+ // )
359+ // if (state.canConnectAccount && state.isSelf) {
360+ // val xOAuthLauncher = rememberLauncherForOAuth(OAuthProvider.X) { accessToken ->
361+ // println("x access token=$accessToken")
362+ // dispatchEvent(ProfileViewModel.Event.LinkXAccount(accessToken))
363+ // }
364+ //
365+ // AnimatedVisibility(
366+ // visible = true,
367+ // enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
368+ // exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
369+ // ) {
370+ // CodeButton(
371+ // modifier = Modifier
372+ // .fillMaxWidth()
373+ // .padding(top = CodeTheme.dimens.grid.x12)
374+ // .padding(horizontal = CodeTheme.dimens.inset),
375+ // buttonState = ButtonState.Filled,
376+ // onClick = { xOAuthLauncher.launch(OAuthProvider.X.launchIntent(context)) },
377+ // content = {
378+ // Image(
379+ // painter = rememberVectorPainter(image = ImageVector.vectorResource(id = R.drawable.ic_twitter_x)),
380+ // colorFilter = ColorFilter.tint(Color.Black),
381+ // contentDescription = null
382+ // )
383+ // Spacer(Modifier.width(CodeTheme.dimens.grid.x2))
384+ // Text(
385+ // text = stringResource(R.string.action_connectYourAccount),
386+ // )
387+ // }
388+ // )
389+ // }
390+ // }
391+ // }
392+ // } else {
393+ // // Linked account state
394+ // state.linkedSocialProfile?.let { linkedProfile ->
395+ // Column(
396+ // modifier = Modifier.fillMaxSize(),
397+ // horizontalAlignment = Alignment.CenterHorizontally
398+ // ) {
399+ // SocialUserDisplay(
400+ // modifier = Modifier.fillMaxWidth(),
401+ // profile = linkedProfile
402+ // )
403+ //
404+ // state.username?.let { username ->
405+ // AnimatedVisibility(
406+ // visible = true,
407+ // enter = fadeIn(),
408+ // exit = fadeOut() + shrinkVertically()
409+ // ) {
410+ // Text(
411+ // modifier = Modifier.fillMaxWidth(),
412+ // text = username,
413+ // style = CodeTheme.typography.textSmall,
414+ // color = CodeTheme.colors.textSecondary,
415+ // textAlign = TextAlign.Center
416+ // )
417+ // }
418+ // }
419+ //
420+ // when (linkedProfile) {
421+ // is SocialProfile.Unknown -> Unit
422+ // is SocialProfile.X -> {
423+ // AnimatedVisibility(
424+ // visible = true,
425+ // enter = fadeIn(),
426+ // exit = fadeOut() + shrinkVertically()
427+ // ) {
428+ // Column(horizontalAlignment = Alignment.CenterHorizontally) {
429+ // Text(
430+ // modifier = Modifier
431+ // .fillMaxWidth()
432+ // .padding(top = CodeTheme.dimens.grid.x8),
433+ // text = "${linkedProfile.followerCountFormatted} Followers",
434+ // style = CodeTheme.typography.textSmall,
435+ // color = CodeTheme.colors.textSecondary,
436+ // textAlign = TextAlign.Center
437+ // )
438+ // Text(
439+ // modifier = Modifier
440+ // .fillMaxWidth(0.70f)
441+ // .padding(top = CodeTheme.dimens.grid.x1),
442+ // text = linkedProfile.description,
443+ // style = CodeTheme.typography.textSmall,
444+ // color = CodeTheme.colors.textSecondary,
445+ // textAlign = TextAlign.Center,
446+ // )
447+ // }
448+ // }
449+ // }
450+ // }
451+ //
452+ // if (!isInTab) {
453+ // AnimatedVisibility(
454+ // visible = true,
455+ // enter = fadeIn() + slideInVertically(initialOffsetY = { it / 2 }),
456+ // exit = fadeOut() + slideOutVertically(targetOffsetY = { it / 2 })
457+ // ) {
458+ // CodeButton(
459+ // modifier = Modifier
460+ // .fillMaxWidth()
461+ // .padding(top = CodeTheme.dimens.grid.x12)
462+ // .padding(horizontal = CodeTheme.dimens.inset),
463+ // buttonState = ButtonState.Filled,
464+ // onClick = { uriHandler.openUri(linkedProfile.profileUrl) },
465+ // text = stringResource(R.string.action_openProfileOnPlatform, linkedProfile.platformTypeName)
466+ // )
467+ // }
468+ // }
469+ // }
470+ // }
471+ // }
472+ // }
327473 }
328474}
329475
0 commit comments