2023-01-11 18:31:20 +00:00
|
|
|
package com.vitorpamplona.amethyst.ui.note
|
|
|
|
|
2023-06-16 19:22:44 +00:00
|
|
|
import android.content.Context
|
|
|
|
import android.util.Log
|
2023-06-26 18:25:46 +00:00
|
|
|
import androidx.compose.animation.Crossfade
|
|
|
|
import androidx.compose.foundation.layout.Row
|
2023-06-20 01:10:01 +00:00
|
|
|
import androidx.compose.foundation.layout.Spacer
|
2023-06-16 19:22:44 +00:00
|
|
|
import androidx.compose.material.IconButton
|
2023-01-11 18:31:20 +00:00
|
|
|
import androidx.compose.material.MaterialTheme
|
|
|
|
import androidx.compose.material.Text
|
|
|
|
import androidx.compose.runtime.Composable
|
2023-06-21 16:47:53 +00:00
|
|
|
import androidx.compose.runtime.derivedStateOf
|
2023-02-01 01:12:24 +00:00
|
|
|
import androidx.compose.runtime.getValue
|
|
|
|
import androidx.compose.runtime.livedata.observeAsState
|
2023-05-16 01:26:59 +00:00
|
|
|
import androidx.compose.runtime.remember
|
2023-07-04 15:44:28 +00:00
|
|
|
import androidx.compose.ui.Alignment
|
2023-01-19 22:56:44 +00:00
|
|
|
import androidx.compose.ui.Modifier
|
2023-06-16 19:22:44 +00:00
|
|
|
import androidx.compose.ui.platform.LocalContext
|
|
|
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
2023-01-11 18:31:20 +00:00
|
|
|
import androidx.compose.ui.text.font.FontWeight
|
2023-01-19 22:56:44 +00:00
|
|
|
import androidx.compose.ui.text.style.TextOverflow
|
2023-06-16 19:22:44 +00:00
|
|
|
import androidx.lifecycle.LifecycleOwner
|
2023-06-23 16:02:27 +00:00
|
|
|
import androidx.lifecycle.map
|
2023-02-01 01:12:24 +00:00
|
|
|
import com.vitorpamplona.amethyst.model.Note
|
2023-01-11 18:31:20 +00:00
|
|
|
import com.vitorpamplona.amethyst.model.User
|
2023-06-16 19:22:44 +00:00
|
|
|
import com.vitorpamplona.amethyst.service.tts.TextToSpeechHelper
|
2023-06-06 19:51:43 +00:00
|
|
|
import com.vitorpamplona.amethyst.ui.actions.ImmutableListOfLists
|
2023-05-16 01:26:59 +00:00
|
|
|
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
2023-06-16 20:18:06 +00:00
|
|
|
import com.vitorpamplona.amethyst.ui.theme.StdButtonSizeModifier
|
2023-06-20 01:10:01 +00:00
|
|
|
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
2023-06-10 14:08:06 +00:00
|
|
|
import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
2023-01-11 18:31:20 +00:00
|
|
|
|
|
|
|
@Composable
|
2023-07-04 15:44:28 +00:00
|
|
|
fun NoteUsernameDisplay(baseNote: Note, weight: Modifier = Modifier, showPlayButton: Boolean = true) {
|
2023-06-23 16:02:27 +00:00
|
|
|
val authorState by baseNote.live().metadata.map {
|
|
|
|
it.note.author
|
2023-06-26 18:25:46 +00:00
|
|
|
}.observeAsState(baseNote.author)
|
2023-02-01 01:12:24 +00:00
|
|
|
|
2023-06-26 18:25:46 +00:00
|
|
|
Crossfade(targetState = authorState, modifier = weight) {
|
|
|
|
it?.let {
|
2023-07-04 15:44:28 +00:00
|
|
|
UsernameDisplay(it, weight, showPlayButton)
|
2023-06-26 18:25:46 +00:00
|
|
|
}
|
2023-06-23 16:02:27 +00:00
|
|
|
}
|
2023-02-01 01:12:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
2023-07-04 15:44:28 +00:00
|
|
|
fun UsernameDisplay(baseUser: User, weight: Modifier = Modifier, showPlayButton: Boolean = true) {
|
2023-06-21 16:47:53 +00:00
|
|
|
val npubDisplay by remember {
|
|
|
|
derivedStateOf {
|
|
|
|
baseUser.pubkeyDisplayHex()
|
|
|
|
}
|
|
|
|
}
|
2023-06-26 18:25:46 +00:00
|
|
|
|
|
|
|
val userMetadata by baseUser.live().metadata.map {
|
|
|
|
it.user.info
|
|
|
|
}.observeAsState(baseUser.info)
|
|
|
|
|
|
|
|
Crossfade(targetState = userMetadata, modifier = weight) {
|
|
|
|
if (it != null) {
|
2023-07-04 15:44:28 +00:00
|
|
|
UserNameDisplay(it.bestUsername(), it.bestDisplayName(), npubDisplay, it.tags, weight, showPlayButton)
|
2023-06-26 18:25:46 +00:00
|
|
|
} else {
|
|
|
|
NPubDisplay(npubDisplay, weight)
|
2023-06-21 16:47:53 +00:00
|
|
|
}
|
|
|
|
}
|
2023-05-06 23:18:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
private fun UserNameDisplay(
|
|
|
|
bestUserName: String?,
|
|
|
|
bestDisplayName: String?,
|
|
|
|
npubDisplay: String,
|
2023-06-06 19:51:43 +00:00
|
|
|
tags: ImmutableListOfLists<String>?,
|
2023-07-04 15:44:28 +00:00
|
|
|
modifier: Modifier,
|
|
|
|
showPlayButton: Boolean = true
|
2023-05-06 23:18:15 +00:00
|
|
|
) {
|
2023-06-21 16:47:53 +00:00
|
|
|
if (bestUserName != null && bestDisplayName != null && bestDisplayName != bestUserName) {
|
2023-07-04 15:44:28 +00:00
|
|
|
UserAndUsernameDisplay(bestDisplayName, tags, bestUserName, modifier, showPlayButton)
|
2023-05-06 23:18:15 +00:00
|
|
|
} else if (bestDisplayName != null) {
|
2023-07-04 15:44:28 +00:00
|
|
|
UserDisplay(bestDisplayName, tags, modifier, showPlayButton)
|
2023-05-06 23:18:15 +00:00
|
|
|
} else if (bestUserName != null) {
|
2023-07-04 15:44:28 +00:00
|
|
|
UserDisplay(bestUserName, tags, modifier, showPlayButton)
|
2023-03-07 18:46:44 +00:00
|
|
|
} else {
|
2023-06-21 16:47:53 +00:00
|
|
|
NPubDisplay(npubDisplay, modifier)
|
2023-03-07 18:46:44 +00:00
|
|
|
}
|
|
|
|
}
|
2023-06-16 19:22:44 +00:00
|
|
|
|
2023-06-21 16:47:53 +00:00
|
|
|
@Composable
|
|
|
|
private fun NPubDisplay(npubDisplay: String, modifier: Modifier) {
|
|
|
|
Text(
|
|
|
|
text = npubDisplay,
|
|
|
|
fontWeight = FontWeight.Bold,
|
|
|
|
maxLines = 1,
|
|
|
|
overflow = TextOverflow.Ellipsis,
|
|
|
|
modifier = modifier
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
private fun UserDisplay(
|
|
|
|
bestDisplayName: String,
|
|
|
|
tags: ImmutableListOfLists<String>?,
|
2023-07-04 15:44:28 +00:00
|
|
|
modifier: Modifier,
|
|
|
|
showPlayButton: Boolean = true
|
2023-06-21 16:47:53 +00:00
|
|
|
) {
|
2023-07-04 15:44:28 +00:00
|
|
|
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
2023-06-26 18:25:46 +00:00
|
|
|
CreateTextWithEmoji(
|
|
|
|
text = bestDisplayName,
|
|
|
|
tags = tags,
|
|
|
|
fontWeight = FontWeight.Bold,
|
|
|
|
maxLines = 1,
|
|
|
|
overflow = TextOverflow.Ellipsis,
|
|
|
|
modifier = modifier
|
|
|
|
)
|
2023-07-04 15:44:28 +00:00
|
|
|
if (showPlayButton) {
|
|
|
|
Spacer(StdHorzSpacer)
|
|
|
|
DrawPlayName(bestDisplayName)
|
|
|
|
}
|
2023-06-26 18:25:46 +00:00
|
|
|
}
|
2023-06-21 16:47:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
private fun UserAndUsernameDisplay(
|
|
|
|
bestDisplayName: String,
|
|
|
|
tags: ImmutableListOfLists<String>?,
|
|
|
|
bestUserName: String,
|
2023-07-04 15:44:28 +00:00
|
|
|
modifier: Modifier,
|
|
|
|
showPlayButton: Boolean = true
|
2023-06-21 16:47:53 +00:00
|
|
|
) {
|
2023-07-04 15:44:28 +00:00
|
|
|
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
2023-06-26 18:25:46 +00:00
|
|
|
CreateTextWithEmoji(
|
|
|
|
text = bestDisplayName,
|
|
|
|
tags = tags,
|
|
|
|
fontWeight = FontWeight.Bold,
|
|
|
|
maxLines = 1
|
|
|
|
)
|
|
|
|
CreateTextWithEmoji(
|
|
|
|
text = remember { "@$bestUserName" },
|
|
|
|
tags = tags,
|
|
|
|
color = MaterialTheme.colors.placeholderText,
|
|
|
|
maxLines = 1,
|
|
|
|
overflow = TextOverflow.Ellipsis,
|
|
|
|
modifier = modifier
|
|
|
|
)
|
2023-07-04 15:44:28 +00:00
|
|
|
if (showPlayButton) {
|
|
|
|
Spacer(StdHorzSpacer)
|
|
|
|
DrawPlayName(bestDisplayName)
|
|
|
|
}
|
2023-06-26 18:25:46 +00:00
|
|
|
}
|
2023-06-21 16:47:53 +00:00
|
|
|
}
|
|
|
|
|
2023-06-16 20:18:06 +00:00
|
|
|
@Composable
|
|
|
|
fun DrawPlayName(name: String) {
|
|
|
|
val context = LocalContext.current
|
|
|
|
val lifecycleOwner = LocalLifecycleOwner.current
|
|
|
|
|
2023-06-21 15:57:49 +00:00
|
|
|
DrawPlayNameIcon {
|
|
|
|
speak(name, context, lifecycleOwner)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Composable
|
|
|
|
fun DrawPlayNameIcon(onClick: () -> Unit) {
|
2023-07-17 15:48:29 +00:00
|
|
|
IconButton(onClick = onClick, modifier = StdButtonSizeModifier) {
|
|
|
|
PlayIcon(modifier = StdButtonSizeModifier, tint = MaterialTheme.colors.placeholderText)
|
2023-06-16 20:18:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-16 19:22:44 +00:00
|
|
|
private fun speak(
|
|
|
|
message: String,
|
|
|
|
context: Context,
|
|
|
|
owner: LifecycleOwner
|
|
|
|
) {
|
|
|
|
TextToSpeechHelper
|
|
|
|
.getInstance(context)
|
|
|
|
.registerLifecycle(owner)
|
|
|
|
.speak(message)
|
|
|
|
.highlight()
|
|
|
|
.onDone {
|
|
|
|
Log.d("TextToSpeak", "speak: done")
|
|
|
|
}
|
|
|
|
.onError {
|
|
|
|
Log.d("TextToSpeak", "speak error: $it")
|
|
|
|
}
|
|
|
|
}
|