package com.suno.android.common_ui.components.omni import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.suno.android.common_core_utils.model.Url import com.suno.android.common_core_utils.model.UserHandle import com.suno.android.common_ui.R import com.suno.android.common_ui.components.ArtistMediumDetail import com.suno.android.common_ui.components.buttons.RoundedButton import com.suno.android.common_ui.components.indicators.Pill import com.suno.android.common_ui.components.list_items.comments.MentionState import com.suno.android.common_ui.components.list_items.comments.TextWithMentions import com.suno.android.common_ui.theme.DarkBackgroundPrimary import com.suno.android.common_ui.theme.DarkTextPrimary import com.suno.android.common_ui.theme.ExtendedTheme import com.suno.android.common_ui.theme.SunoTheme import com.suno.android.common_res.R as CommonResR @Composable fun OmniPlayerHeader( title: String?, artistName: String?, artistAvatarImageUrl: Url?, caption: String?, captionMentionsStates: List?, clipModelName: String? = null, onArtistHandleClicked: (UserHandle?) -> Unit, onDismissClicked: () -> Unit, onUpgradeClicked: () -> Unit, isPreviewClip: Boolean? = null, ) { var isCaptionExpanded by remember { mutableStateOf(false) } var captionExpandable by remember { mutableStateOf(false) } Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp), ) { Column( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(8.dp), ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(4.dp), ) { Text( textAlign = TextAlign.Start, text = if (title.isNullOrEmpty()) { stringResource(CommonResR.string.untitled) } else { title }, color = Color.White, style = ExtendedTheme.typography.body, lineHeight = 24.sp, ) if (isPreviewClip == true) { Pill( text = listOfNotNull( clipModelName, stringResource(CommonResR.string.preview), ).joinToString(" "), color = ExtendedTheme.colors.sunoPink, contentColor = Color.White, ) } } ArtistMediumDetail( modifier = Modifier .clip(MaterialTheme.shapes.small) .clickable { onArtistHandleClicked.invoke(null) }, creatorAvatarUrl = artistAvatarImageUrl, creatorName = artistName.orEmpty(), artistTextColor = DarkTextPrimary, ) if (isPreviewClip == true) { RoundedButton( buttonText = stringResource(CommonResR.string.upgrade_for_full_access), contentColor = ExtendedTheme.colors.sunoPink, backgroundColor = Color.White, contentPadding = PaddingValues(horizontal = 24.dp, vertical = 0.dp), onClick = { onUpgradeClicked.invoke() }, ) } else if (!caption.isNullOrEmpty()) { TextWithMentions( comment = caption.trim(), userMentions = captionMentionsStates, onProfileClicked = { handle -> onArtistHandleClicked(handle) }, ) if (captionExpandable && !isCaptionExpanded) { Text( modifier = Modifier.clickable { isCaptionExpanded = true }, text = stringResource(CommonResR.string.read_more), style = ExtendedTheme.typography.smallSubtitle, color = ExtendedTheme.colors.sunoPink, ) } } } CircleIconButton( modifier = Modifier.alpha(0.7f), bgColor = DarkBackgroundPrimary.copy(alpha = 0.65f), iconColor = DarkTextPrimary, vectorDrawableResId = R.drawable.chevron_down, contentDescription = "Dismiss Fullscreen Player", onClick = { onDismissClicked.invoke() }, ) } } @Preview @Composable private fun OmniPlayerHeader_Preview() { SunoTheme { OmniPlayerHeader( title = "Title Text That is a little bit long actually extremely long so much so that", artistName = "ZeroNanachi \uD83D\uDE3C\uD83C\uDF63", artistAvatarImageUrl = null, onArtistHandleClicked = {}, caption = """Cyberpunk vibes activated \uD83E\uDD16⚡\uFE0F An android on a mission, weaving through neon |dreams and dystopian beats. Who else feels the future calling? \uD83D\uDD25 #CyberpunkAndroid |#MusicOfTheFuture """.trimMargin(), captionMentionsStates = listOf(), onDismissClicked = {}, onUpgradeClicked = {}, ) } } @Preview @Composable private fun OmniPlayerHeader_PreviewClip_Preview() { SunoTheme { OmniPlayerHeader( title = "Title Text That is a little bit long actually extremely long so much so that", artistName = "ZeroNanachi \uD83D\uDE3C\uD83C\uDF63", artistAvatarImageUrl = null, caption = """Cyberpunk vibes activated \uD83E\uDD16⚡\uFE0F An android on a mission, weaving through neon |dreams and dystopian beats. Who else feels the future calling? \uD83D\uDD25 #CyberpunkAndroid |#MusicOfTheFuture """.trimMargin(), onArtistHandleClicked = {}, captionMentionsStates = listOf(), onDismissClicked = {}, onUpgradeClicked = {}, isPreviewClip = true, ) } }