NoteCompose refactoring
This commit is contained in:
@@ -31,6 +31,11 @@ class PrivateDmEvent(
|
||||
*/
|
||||
fun replyTo() = tags.firstOrNull { it.size > 1 && it[0] == "e" }?.get(1)
|
||||
|
||||
fun with(pubkeyHex: String): Boolean {
|
||||
return pubkeyHex == pubKey ||
|
||||
tags.firstOrNull { it.size > 1 && it[0] == "p" }?.getOrNull(1) == pubkeyHex
|
||||
}
|
||||
|
||||
fun plainContent(privKey: ByteArray, pubKey: ByteArray): String? {
|
||||
return try {
|
||||
val sharedSecret = Utils.getSharedSecret(privKey, pubKey)
|
||||
|
||||
@@ -359,9 +359,9 @@ fun BechLink(word: String, canPreview: Boolean, backgroundColor: Color, accountV
|
||||
LocalCache.checkGetOrCreateNote(it.hex)?.let { note ->
|
||||
baseNotePair = Pair(note, it.additionalChars)
|
||||
}
|
||||
} else {
|
||||
nip19Route = it
|
||||
}
|
||||
|
||||
nip19Route = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.vitorpamplona.amethyst.NotificationCache
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.BadgeCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -48,7 +47,6 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL
|
||||
|
||||
val context = LocalContext.current.applicationContext
|
||||
|
||||
val noteEvent = note?.event
|
||||
var popupExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
if (note == null) {
|
||||
@@ -73,15 +71,7 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL
|
||||
Column(
|
||||
modifier = Modifier.background(backgroundColor).combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent !is ChannelMessageEvent) {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
note.channel()?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
}
|
||||
routeFor(note, accountViewModel.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
|
||||
@@ -74,7 +74,7 @@ fun HiddenNote(reports: Set<Note>, loggedIn: User, modifier: Modifier = Modifier
|
||||
FlowRow(modifier = Modifier.padding(top = 10.dp)) {
|
||||
reports.forEach {
|
||||
NoteAuthorPicture(
|
||||
note = it,
|
||||
baseNote = it,
|
||||
navController = navController,
|
||||
userAccount = loggedIn,
|
||||
size = 35.dp
|
||||
|
||||
@@ -28,7 +28,6 @@ import androidx.navigation.NavController
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import com.vitorpamplona.amethyst.NotificationCache
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.BoostSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -68,15 +67,7 @@ fun BoostSetCompose(boostSetCard: BoostSetCard, isInnerNote: Boolean = false, ro
|
||||
Column(
|
||||
modifier = Modifier.background(backgroundColor).combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent !is ChannelMessageEvent) {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
note.channel()?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
}
|
||||
routeFor(note, account.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
@@ -109,7 +100,7 @@ fun BoostSetCompose(boostSetCard: BoostSetCard, isInnerNote: Boolean = false, ro
|
||||
FlowRow() {
|
||||
boostSetCard.boostEvents.forEach {
|
||||
NoteAuthorPicture(
|
||||
note = it,
|
||||
baseNote = it,
|
||||
navController = navController,
|
||||
userAccount = account.userProfile(),
|
||||
size = 35.dp
|
||||
|
||||
@@ -28,7 +28,6 @@ import androidx.navigation.NavController
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import com.vitorpamplona.amethyst.NotificationCache
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.LikeSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -68,15 +67,7 @@ fun LikeSetCompose(likeSetCard: LikeSetCard, isInnerNote: Boolean = false, route
|
||||
Column(
|
||||
modifier = Modifier.background(backgroundColor).combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent !is ChannelMessageEvent) {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
note.channel()?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
}
|
||||
routeFor(note, account.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
@@ -109,7 +100,7 @@ fun LikeSetCompose(likeSetCard: LikeSetCard, isInnerNote: Boolean = false, route
|
||||
FlowRow() {
|
||||
likeSetCard.likeEvents.forEach {
|
||||
NoteAuthorPicture(
|
||||
note = it,
|
||||
baseNote = it,
|
||||
navController = navController,
|
||||
userAccount = account.userProfile(),
|
||||
size = 35.dp
|
||||
|
||||
@@ -26,9 +26,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.vitorpamplona.amethyst.NotificationCache
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.MessageSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -66,30 +63,7 @@ fun MessageSetCompose(messageSetCard: MessageSetCard, isInnerNote: Boolean = fal
|
||||
Column(
|
||||
modifier = Modifier.background(backgroundColor).combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent is ChannelMessageEvent) {
|
||||
note.channel()?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
} else if (noteEvent is PrivateDmEvent) {
|
||||
val replyAuthorBase =
|
||||
(note.event as? PrivateDmEvent)
|
||||
?.recipientPubKey()
|
||||
?.let { LocalCache.getOrCreateUser(it) }
|
||||
|
||||
var userToComposeOn = note.author!!
|
||||
|
||||
if (replyAuthorBase != null) {
|
||||
if (note.author == accountViewModel.userProfile()) {
|
||||
userToComposeOn = replyAuthorBase
|
||||
}
|
||||
}
|
||||
|
||||
navController.navigate("Room/${userToComposeOn.pubkeyHex}")
|
||||
} else {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
routeFor(note, accountViewModel.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
@@ -120,7 +94,7 @@ fun MessageSetCompose(messageSetCard: MessageSetCard, isInnerNote: Boolean = fal
|
||||
|
||||
Column(modifier = Modifier.padding(start = if (!isInnerNote) 10.dp else 0.dp)) {
|
||||
NoteCompose(
|
||||
baseNote = note,
|
||||
baseNote = messageSetCard.note,
|
||||
routeForLastRead = null,
|
||||
isBoostedNote = true,
|
||||
addMarginTop = false,
|
||||
|
||||
@@ -37,9 +37,7 @@ import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.service.model.LnZapRequestEvent
|
||||
import com.vitorpamplona.amethyst.service.model.PrivateDmEvent
|
||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||
import com.vitorpamplona.amethyst.ui.screen.MultiSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
@@ -83,32 +81,7 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
.background(backgroundColor)
|
||||
.combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent is ChannelMessageEvent) {
|
||||
note
|
||||
.channel()
|
||||
?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
} else if (noteEvent is PrivateDmEvent) {
|
||||
val replyAuthorBase =
|
||||
(note.event as? PrivateDmEvent)
|
||||
?.recipientPubKey()
|
||||
?.let { LocalCache.getOrCreateUser(it) }
|
||||
|
||||
var userToComposeOn = note.author!!
|
||||
|
||||
if (replyAuthorBase != null) {
|
||||
if (note.author == accountViewModel.userProfile()) {
|
||||
userToComposeOn = replyAuthorBase
|
||||
}
|
||||
}
|
||||
|
||||
navController.navigate("Room/${userToComposeOn.pubkeyHex}")
|
||||
} else {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
routeFor(note, account.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
@@ -195,7 +168,7 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
}
|
||||
|
||||
NoteCompose(
|
||||
baseNote = note,
|
||||
baseNote = multiSetCard.note,
|
||||
routeForLastRead = null,
|
||||
modifier = Modifier.padding(top = 5.dp),
|
||||
isBoostedNote = true,
|
||||
@@ -225,7 +198,7 @@ fun AuthorGalleryZaps(
|
||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||
FlowRow() {
|
||||
authorNotes.forEach {
|
||||
AuthorPictureAndComment(it.key, it.value, navController, accountUser, accountViewModel)
|
||||
AuthorPictureAndComment(it.key, navController, accountUser, accountViewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,7 +207,6 @@ fun AuthorGalleryZaps(
|
||||
@Composable
|
||||
private fun AuthorPictureAndComment(
|
||||
zapRequest: Note,
|
||||
zapEvent: Note,
|
||||
navController: NavController,
|
||||
accountUser: User,
|
||||
accountViewModel: AccountViewModel
|
||||
|
||||
@@ -127,10 +127,6 @@ fun NoteComposeInner(
|
||||
var popupExpanded by remember { mutableStateOf(false) }
|
||||
var showHiddenNote by remember { mutableStateOf(false) }
|
||||
|
||||
val context = LocalContext.current.applicationContext
|
||||
|
||||
var moreActionsExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
var isAcceptable by remember { mutableStateOf(true) }
|
||||
var canPreview by remember { mutableStateOf(true) }
|
||||
|
||||
@@ -205,28 +201,7 @@ fun NoteComposeInner(
|
||||
Column(
|
||||
modifier = modifier.combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent is ChannelMessageEvent) {
|
||||
baseChannel?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
} else if (noteEvent is PrivateDmEvent) {
|
||||
val replyAuthorBase =
|
||||
(note.event as? PrivateDmEvent)
|
||||
?.recipientPubKey()
|
||||
?.let { LocalCache.getOrCreateUser(it) }
|
||||
|
||||
var userToComposeOn = note.author!!
|
||||
|
||||
if (replyAuthorBase != null) {
|
||||
if (note.author == accountViewModel.userProfile()) {
|
||||
userToComposeOn = replyAuthorBase
|
||||
}
|
||||
}
|
||||
|
||||
navController.navigate("Room/${userToComposeOn.pubkeyHex}")
|
||||
} else {
|
||||
navController.navigate("Note/${note.idHex}")
|
||||
}
|
||||
routeFor(note, loggedIn)?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
).background(backgroundColor)
|
||||
@@ -244,281 +219,88 @@ fun NoteComposeInner(
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(start = if (!isBoostedNote && !isQuotedNote) 10.dp else 0.dp)
|
||||
modifier = Modifier
|
||||
.padding(start = if (!isBoostedNote && !isQuotedNote) 10.dp else 0.dp)
|
||||
) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (isQuotedNote) {
|
||||
NoteAuthorPicture(note, navController, loggedIn, 25.dp)
|
||||
Spacer(Modifier.padding(horizontal = 5.dp))
|
||||
NoteUsernameDisplay(note, Modifier.weight(1f))
|
||||
} else {
|
||||
NoteUsernameDisplay(note, Modifier.weight(1f))
|
||||
}
|
||||
FirstUserInfoRow(
|
||||
baseNote = baseNote,
|
||||
showAuthorPicture = isQuotedNote,
|
||||
account = account,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
|
||||
if (noteEvent is RepostEvent) {
|
||||
Text(
|
||||
" ${stringResource(id = R.string.boosted)}",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||
)
|
||||
} else {
|
||||
DisplayFollowingHashtagsInPost(noteEvent, account, navController)
|
||||
}
|
||||
|
||||
Text(
|
||||
timeAgo(note.createdAt(), context = context),
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 1
|
||||
if (noteEvent !is RepostEvent && !makeItShort && !isQuotedNote) {
|
||||
SecondUserInfoRow(
|
||||
note,
|
||||
account,
|
||||
navController
|
||||
)
|
||||
|
||||
IconButton(
|
||||
modifier = Modifier.size(24.dp),
|
||||
onClick = { moreActionsExpanded = true }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
null,
|
||||
modifier = Modifier.size(15.dp),
|
||||
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||
)
|
||||
|
||||
NoteDropDownMenu(baseNote, moreActionsExpanded, { moreActionsExpanded = false }, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
if (noteEvent !is RepostEvent && note.author != null && !makeItShort && !isQuotedNote) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
ObserveDisplayNip05Status(note.author!!, Modifier.weight(1f))
|
||||
|
||||
val baseReward = noteEvent.getReward()
|
||||
if (baseReward != null) {
|
||||
DisplayReward(baseReward, baseNote, account, navController)
|
||||
}
|
||||
|
||||
val pow = noteEvent.getPoWRank()
|
||||
if (pow > 20) {
|
||||
DisplayPoW(pow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
|
||||
if (!makeItShort && noteEvent is TextNoteEvent && (note.replyTo != null || noteEvent.mentions().isNotEmpty())) {
|
||||
val replyingDirectlyTo = note.replyTo?.lastOrNull()
|
||||
if (replyingDirectlyTo != null && unPackReply) {
|
||||
NoteCompose(
|
||||
baseNote = replyingDirectlyTo,
|
||||
isQuotedNote = true,
|
||||
modifier = Modifier
|
||||
.padding(top = 5.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(shape = RoundedCornerShape(15.dp))
|
||||
.border(
|
||||
1.dp,
|
||||
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
|
||||
RoundedCornerShape(15.dp)
|
||||
),
|
||||
unPackReply = false,
|
||||
makeItShort = true,
|
||||
parentBackgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.05f).compositeOver(backgroundColor),
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
} else {
|
||||
ReplyInformation(note.replyTo, noteEvent.mentions(), account, navController)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(5.dp))
|
||||
} else if (!makeItShort && noteEvent is ChannelMessageEvent && (note.replyTo != null || noteEvent.mentions().isNotEmpty())) {
|
||||
val sortedMentions = noteEvent.mentions()
|
||||
.mapNotNull { LocalCache.checkGetOrCreateUser(it) }
|
||||
.toSet()
|
||||
.sortedBy { loggedIn.isFollowingCached(it) }
|
||||
|
||||
note.channel()?.let {
|
||||
ReplyInformationChannel(note.replyTo, sortedMentions, it, navController)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(5.dp))
|
||||
if (!makeItShort) {
|
||||
ReplyRow(
|
||||
note,
|
||||
unPackReply,
|
||||
backgroundColor,
|
||||
account,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
|
||||
if (noteEvent is ReactionEvent || noteEvent is RepostEvent) {
|
||||
note.replyTo?.lastOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = true,
|
||||
unPackReply = false,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
when (noteEvent) {
|
||||
is ReactionEvent -> {
|
||||
RenderReaction(note, backgroundColor, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is RepostEvent -> {
|
||||
RenderRepost(note, backgroundColor, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is ReportEvent -> {
|
||||
RenderReport(note)
|
||||
}
|
||||
|
||||
is LongTextNoteEvent -> {
|
||||
RenderLongFormContent(note, loggedIn, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is BadgeAwardEvent -> {
|
||||
RenderBadgeAward(note, backgroundColor, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is PrivateDmEvent -> {
|
||||
RenderPrivateMessage(note, makeItShort, canPreview, backgroundColor, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is HighlightEvent -> {
|
||||
RenderHighlight(note, makeItShort, canPreview, backgroundColor, accountViewModel, navController)
|
||||
}
|
||||
|
||||
is PollNoteEvent -> {
|
||||
RenderPoll(
|
||||
note,
|
||||
makeItShort,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
|
||||
// Reposts have trash in their contents.
|
||||
if (noteEvent is ReactionEvent) {
|
||||
val refactorReactionText =
|
||||
if (noteEvent.content == "+") "❤" else noteEvent.content
|
||||
|
||||
Text(
|
||||
text = refactorReactionText
|
||||
else -> {
|
||||
RenderTextEvent(
|
||||
note,
|
||||
makeItShort,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
} else if (noteEvent is ReportEvent) {
|
||||
val reportType = (noteEvent.reportedPost() + noteEvent.reportedAuthor()).map {
|
||||
when (it.reportType) {
|
||||
ReportEvent.ReportType.EXPLICIT -> stringResource(R.string.explicit_content)
|
||||
ReportEvent.ReportType.NUDITY -> stringResource(R.string.nudity)
|
||||
ReportEvent.ReportType.PROFANITY -> stringResource(R.string.profanity_hateful_speech)
|
||||
ReportEvent.ReportType.SPAM -> stringResource(R.string.spam)
|
||||
ReportEvent.ReportType.IMPERSONATION -> stringResource(R.string.impersonation)
|
||||
ReportEvent.ReportType.ILLEGAL -> stringResource(R.string.illegal_behavior)
|
||||
}
|
||||
}.toSet().joinToString(", ")
|
||||
|
||||
Text(
|
||||
text = reportType
|
||||
)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 40.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
} else if (noteEvent is LongTextNoteEvent) {
|
||||
LongFormHeader(noteEvent, note, loggedIn)
|
||||
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
} else if (noteEvent is BadgeAwardEvent && !note.replyTo.isNullOrEmpty()) {
|
||||
Text(text = stringResource(R.string.award_granted_to))
|
||||
|
||||
FlowRow(modifier = Modifier.padding(top = 5.dp)) {
|
||||
noteEvent.awardees()
|
||||
.map { LocalCache.getOrCreateUser(it) }
|
||||
.forEach {
|
||||
UserPicture(
|
||||
user = it,
|
||||
navController = navController,
|
||||
userAccount = loggedIn,
|
||||
size = 35.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
note.replyTo?.firstOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = false,
|
||||
isQuotedNote = true,
|
||||
unPackReply = false,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
} else if (noteEvent is PrivateDmEvent &&
|
||||
noteEvent.recipientPubKey() != loggedIn.pubkeyHex &&
|
||||
note.author !== loggedIn
|
||||
) {
|
||||
val recipient = noteEvent.recipientPubKey()?.let { LocalCache.checkGetOrCreateUser(it) }
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
stringResource(
|
||||
id = R.string.private_conversation_notification,
|
||||
"@${note.author?.pubkeyNpub()}",
|
||||
"@${recipient?.pubkeyNpub()}"
|
||||
),
|
||||
canPreview = !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
noteEvent.tags(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
} else if (noteEvent is HighlightEvent) {
|
||||
DisplayHighlight(
|
||||
noteEvent.quote(),
|
||||
noteEvent.author(),
|
||||
noteEvent.inUrl(),
|
||||
makeItShort,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
} else {
|
||||
val eventContent = accountViewModel.decrypt(note)
|
||||
|
||||
if (eventContent != null) {
|
||||
if (makeItShort && note.author == loggedIn) {
|
||||
Text(
|
||||
text = eventContent,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
eventContent,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
noteEvent.tags(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
|
||||
}
|
||||
|
||||
if (noteEvent is PollNoteEvent) {
|
||||
PollNote(
|
||||
note,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
NoteQuickActionMenu(note, popupExpanded, { popupExpanded = false }, accountViewModel)
|
||||
@@ -528,6 +310,508 @@ fun NoteComposeInner(
|
||||
}
|
||||
}
|
||||
|
||||
fun routeFor(note: Note, loggedIn: User): String? {
|
||||
val noteEvent = note.event
|
||||
|
||||
if (noteEvent is ChannelMessageEvent || noteEvent is ChannelCreateEvent || noteEvent is ChannelMetadataEvent) {
|
||||
note.channel()?.let {
|
||||
return "Channel/${it.idHex}"
|
||||
}
|
||||
} else if (noteEvent is PrivateDmEvent) {
|
||||
val replyAuthorBase =
|
||||
(note.event as? PrivateDmEvent)
|
||||
?.recipientPubKey()
|
||||
?.let { LocalCache.getOrCreateUser(it) }
|
||||
|
||||
var userToComposeOn = note.author!!
|
||||
|
||||
if (replyAuthorBase != null) {
|
||||
if (note.author == loggedIn) {
|
||||
userToComposeOn = replyAuthorBase
|
||||
}
|
||||
}
|
||||
|
||||
return "Room/${userToComposeOn.pubkeyHex}"
|
||||
} else {
|
||||
return "Note/${note.idHex}"
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderTextEvent(
|
||||
note: Note,
|
||||
makeItShort: Boolean,
|
||||
canPreview: Boolean,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event ?: return
|
||||
|
||||
val eventContent = accountViewModel.decrypt(note)
|
||||
|
||||
if (eventContent != null) {
|
||||
if (makeItShort && accountViewModel.isLoggedUser(note.author)) {
|
||||
Text(
|
||||
text = eventContent,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = eventContent,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
tags = noteEvent.tags(),
|
||||
backgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
|
||||
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
|
||||
}
|
||||
}
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderPoll(
|
||||
note: Note,
|
||||
makeItShort: Boolean,
|
||||
canPreview: Boolean,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event as? PollNoteEvent ?: return
|
||||
val eventContent = noteEvent.content()
|
||||
|
||||
if (makeItShort && accountViewModel.isLoggedUser(note.author)) {
|
||||
Text(
|
||||
text = eventContent,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
eventContent,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
noteEvent.tags(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
|
||||
|
||||
PollNote(
|
||||
note,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderHighlight(
|
||||
note: Note,
|
||||
makeItShort: Boolean,
|
||||
canPreview: Boolean,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event as? HighlightEvent ?: return
|
||||
|
||||
DisplayHighlight(
|
||||
noteEvent.quote(),
|
||||
noteEvent.author(),
|
||||
noteEvent.inUrl(),
|
||||
makeItShort,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderPrivateMessage(
|
||||
note: Note,
|
||||
makeItShort: Boolean,
|
||||
canPreview: Boolean,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event as? PrivateDmEvent ?: return
|
||||
val withMe = noteEvent.with(accountViewModel.userProfile().pubkeyHex)
|
||||
|
||||
if (withMe) {
|
||||
val eventContent = accountViewModel.decrypt(note)
|
||||
|
||||
if (eventContent != null) {
|
||||
if (makeItShort && accountViewModel.isLoggedUser(note.author)) {
|
||||
Text(
|
||||
text = eventContent,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
} else {
|
||||
TranslatableRichTextViewer(
|
||||
content = eventContent,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
tags = noteEvent.tags(),
|
||||
backgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
|
||||
DisplayUncitedHashtags(noteEvent.hashtags(), eventContent, navController)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val recipient = noteEvent.recipientPubKey()?.let { LocalCache.checkGetOrCreateUser(it) }
|
||||
|
||||
TranslatableRichTextViewer(
|
||||
stringResource(
|
||||
id = R.string.private_conversation_notification,
|
||||
"@${note.author?.pubkeyNpub()}",
|
||||
"@${recipient?.pubkeyNpub()}"
|
||||
),
|
||||
canPreview = !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
noteEvent.tags(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
|
||||
if (!makeItShort) {
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
}
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderBadgeAward(
|
||||
note: Note,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
if (note.replyTo.isNullOrEmpty()) return
|
||||
|
||||
val noteEvent = note.event as? BadgeAwardEvent ?: return
|
||||
|
||||
Text(text = stringResource(R.string.award_granted_to))
|
||||
|
||||
FlowRow(modifier = Modifier.padding(top = 5.dp)) {
|
||||
noteEvent.awardees()
|
||||
.map { LocalCache.getOrCreateUser(it) }
|
||||
.forEach {
|
||||
UserPicture(
|
||||
user = it,
|
||||
navController = navController,
|
||||
userAccount = accountViewModel.userProfile(),
|
||||
size = 35.dp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
note.replyTo?.firstOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = false,
|
||||
isQuotedNote = true,
|
||||
unPackReply = false,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderReaction(
|
||||
note: Note,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
note.replyTo?.lastOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = true,
|
||||
unPackReply = false,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
|
||||
// Reposts have trash in their contents.
|
||||
val refactorReactionText =
|
||||
if (note.event?.content() == "+") "❤" else note.event?.content() ?: ""
|
||||
|
||||
Text(
|
||||
text = refactorReactionText
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderRepost(
|
||||
note: Note,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
note.replyTo?.lastOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = true,
|
||||
unPackReply = false,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderLongFormContent(
|
||||
note: Note,
|
||||
loggedIn: User,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event as? LongTextNoteEvent ?: return
|
||||
|
||||
LongFormHeader(noteEvent, note, loggedIn)
|
||||
|
||||
ReactionsRow(note, accountViewModel, navController)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 10.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RenderReport(note: Note) {
|
||||
val noteEvent = note.event as? ReportEvent ?: return
|
||||
|
||||
val reportType = (noteEvent.reportedPost() + noteEvent.reportedAuthor()).map {
|
||||
when (it.reportType) {
|
||||
ReportEvent.ReportType.EXPLICIT -> stringResource(R.string.explicit_content)
|
||||
ReportEvent.ReportType.NUDITY -> stringResource(R.string.nudity)
|
||||
ReportEvent.ReportType.PROFANITY -> stringResource(R.string.profanity_hateful_speech)
|
||||
ReportEvent.ReportType.SPAM -> stringResource(R.string.spam)
|
||||
ReportEvent.ReportType.IMPERSONATION -> stringResource(R.string.impersonation)
|
||||
ReportEvent.ReportType.ILLEGAL -> stringResource(R.string.illegal_behavior)
|
||||
}
|
||||
}.toSet().joinToString(", ")
|
||||
|
||||
Text(
|
||||
text = reportType
|
||||
)
|
||||
|
||||
Divider(
|
||||
modifier = Modifier.padding(top = 40.dp),
|
||||
thickness = 0.25.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ReplyRow(
|
||||
note: Note,
|
||||
unPackReply: Boolean,
|
||||
backgroundColor: Color,
|
||||
account: Account,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event
|
||||
|
||||
if (noteEvent is TextNoteEvent &&
|
||||
(note.replyTo != null || noteEvent.mentions().isNotEmpty())
|
||||
) {
|
||||
val replyingDirectlyTo = note.replyTo?.lastOrNull()
|
||||
if (replyingDirectlyTo != null && unPackReply) {
|
||||
NoteCompose(
|
||||
baseNote = replyingDirectlyTo,
|
||||
isQuotedNote = true,
|
||||
modifier = Modifier
|
||||
.padding(top = 5.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(shape = RoundedCornerShape(15.dp))
|
||||
.border(
|
||||
1.dp,
|
||||
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
|
||||
RoundedCornerShape(15.dp)
|
||||
),
|
||||
unPackReply = false,
|
||||
makeItShort = true,
|
||||
parentBackgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.05f)
|
||||
.compositeOver(backgroundColor),
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
} else {
|
||||
ReplyInformation(note.replyTo, noteEvent.mentions(), account, navController)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(5.dp))
|
||||
} else if (
|
||||
noteEvent is ChannelMessageEvent &&
|
||||
(note.replyTo != null || noteEvent.mentions().isNotEmpty())
|
||||
) {
|
||||
val sortedMentions = noteEvent.mentions()
|
||||
.mapNotNull { LocalCache.checkGetOrCreateUser(it) }
|
||||
.toSet()
|
||||
.sortedBy { account.isFollowing(it) }
|
||||
|
||||
note.channel()?.let {
|
||||
ReplyInformationChannel(note.replyTo, sortedMentions, it, navController)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(5.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SecondUserInfoRow(
|
||||
note: Note,
|
||||
account: Account,
|
||||
navController: NavController
|
||||
) {
|
||||
val noteEvent = note.event ?: return
|
||||
val noteAuthor = note.author ?: return
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
ObserveDisplayNip05Status(noteAuthor, Modifier.weight(1f))
|
||||
|
||||
val baseReward = noteEvent.getReward()
|
||||
if (baseReward != null) {
|
||||
DisplayReward(baseReward, note, account, navController)
|
||||
}
|
||||
|
||||
val pow = noteEvent.getPoWRank()
|
||||
if (pow > 20) {
|
||||
DisplayPoW(pow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun FirstUserInfoRow(
|
||||
baseNote: Note,
|
||||
showAuthorPicture: Boolean,
|
||||
account: Account,
|
||||
accountViewModel: AccountViewModel,
|
||||
navController: NavController
|
||||
) {
|
||||
var moreActionsExpanded by remember { mutableStateOf(false) }
|
||||
val context = LocalContext.current.applicationContext
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (showAuthorPicture) {
|
||||
NoteAuthorPicture(baseNote, navController, account.userProfile(), 25.dp)
|
||||
Spacer(Modifier.padding(horizontal = 5.dp))
|
||||
NoteUsernameDisplay(baseNote, Modifier.weight(1f))
|
||||
} else {
|
||||
NoteUsernameDisplay(baseNote, Modifier.weight(1f))
|
||||
}
|
||||
|
||||
if (baseNote.event is RepostEvent) {
|
||||
Text(
|
||||
" ${stringResource(id = R.string.boosted)}",
|
||||
fontWeight = FontWeight.Bold,
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||
)
|
||||
} else {
|
||||
baseNote.event?.let {
|
||||
DisplayFollowingHashtagsInPost(it, account, navController)
|
||||
}
|
||||
}
|
||||
|
||||
Text(
|
||||
timeAgo(baseNote.createdAt(), context = context),
|
||||
color = MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
|
||||
maxLines = 1
|
||||
)
|
||||
|
||||
IconButton(
|
||||
modifier = Modifier.size(24.dp),
|
||||
onClick = { moreActionsExpanded = true }
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.MoreVert,
|
||||
null,
|
||||
modifier = Modifier.size(15.dp),
|
||||
tint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||
)
|
||||
|
||||
NoteDropDownMenu(
|
||||
baseNote,
|
||||
moreActionsExpanded,
|
||||
{ moreActionsExpanded = false },
|
||||
accountViewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DrawAuthorImages(baseNote: Note, loggedIn: User, navController: NavController) {
|
||||
val baseChannel = baseNote.channel()
|
||||
@@ -626,17 +910,15 @@ fun DisplayHighlight(
|
||||
) {
|
||||
val quote = highlight.split("\n").map { "> *${it.removeSuffix(" ")}*" }.joinToString("\n")
|
||||
|
||||
if (quote != null) {
|
||||
TranslatableRichTextViewer(
|
||||
quote,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
emptyList(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
}
|
||||
TranslatableRichTextViewer(
|
||||
quote,
|
||||
canPreview = canPreview && !makeItShort,
|
||||
Modifier.fillMaxWidth(),
|
||||
emptyList(),
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
navController
|
||||
)
|
||||
|
||||
FlowRow() {
|
||||
authorHex?.let { authorHex ->
|
||||
@@ -1158,13 +1440,13 @@ private fun ShowMoreRelaysButton(onClick: () -> Unit) {
|
||||
|
||||
@Composable
|
||||
fun NoteAuthorPicture(
|
||||
note: Note,
|
||||
baseNote: Note,
|
||||
navController: NavController,
|
||||
userAccount: User,
|
||||
size: Dp,
|
||||
pictureModifier: Modifier = Modifier
|
||||
) {
|
||||
NoteAuthorPicture(note, userAccount, size, pictureModifier) {
|
||||
NoteAuthorPicture(baseNote, userAccount, size, pictureModifier) {
|
||||
navController.navigate("User/${it.pubkeyHex}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import androidx.navigation.NavController
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import com.vitorpamplona.amethyst.NotificationCache
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.service.model.ChannelMessageEvent
|
||||
import com.vitorpamplona.amethyst.ui.screen.ZapSetCard
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||
@@ -70,15 +69,7 @@ fun ZapSetCompose(zapSetCard: ZapSetCard, isInnerNote: Boolean = false, routeFor
|
||||
Column(
|
||||
modifier = Modifier.background(backgroundColor).combinedClickable(
|
||||
onClick = {
|
||||
if (noteEvent !is ChannelMessageEvent) {
|
||||
navController.navigate("Note/${note.idHex}") {
|
||||
launchSingleTop = true
|
||||
}
|
||||
} else {
|
||||
note.channel()?.let {
|
||||
navController.navigate("Channel/${it.idHex}")
|
||||
}
|
||||
}
|
||||
routeFor(note, account.userProfile())?.let { navController.navigate(it) }
|
||||
},
|
||||
onLongClick = { popupExpanded = true }
|
||||
)
|
||||
@@ -113,7 +104,7 @@ fun ZapSetCompose(zapSetCard: ZapSetCard, isInnerNote: Boolean = false, routeFor
|
||||
FlowRow() {
|
||||
zapSetCard.zapEvents.forEach {
|
||||
NoteAuthorPicture(
|
||||
note = it.key,
|
||||
baseNote = it.key,
|
||||
navController = navController,
|
||||
userAccount = account.userProfile(),
|
||||
size = 35.dp
|
||||
|
||||
@@ -94,7 +94,7 @@ fun ZapUserSetCompose(zapSetCard: ZapUserSetCard, isInnerNote: Boolean = false,
|
||||
FlowRow() {
|
||||
zapSetCard.zapEvents.forEach {
|
||||
NoteAuthorPicture(
|
||||
note = it.key,
|
||||
baseNote = it.key,
|
||||
navController = navController,
|
||||
userAccount = account.userProfile(),
|
||||
size = 35.dp
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -32,6 +33,8 @@ import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.ZapSetCompose
|
||||
import com.vitorpamplona.amethyst.ui.note.ZapUserSetCompose
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.measureTimedValue
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
@@ -85,6 +88,7 @@ fun CardFeedView(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
@Composable
|
||||
private fun FeedLoaded(
|
||||
state: CardFeedState.Loaded,
|
||||
@@ -114,61 +118,64 @@ private fun FeedLoaded(
|
||||
state = listState
|
||||
) {
|
||||
itemsIndexed(state.feed.value, key = { _, item -> item.id() }) { _, item ->
|
||||
when (item) {
|
||||
is NoteCard -> NoteCompose(
|
||||
item.note,
|
||||
isBoostedNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is ZapSetCard -> ZapSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is ZapUserSetCard -> ZapUserSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is LikeSetCard -> LikeSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is BoostSetCard -> BoostSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is MultiSetCard -> MultiSetCompose(
|
||||
item,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is BadgeCard -> BadgeCompose(
|
||||
item,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is MessageSetCard -> MessageSetCompose(
|
||||
messageSetCard = item,
|
||||
routeForLastRead = routeForLastRead,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
val (value, elapsed) = measureTimedValue {
|
||||
when (item) {
|
||||
is NoteCard -> NoteCompose(
|
||||
item.note,
|
||||
isBoostedNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is ZapSetCard -> ZapSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is ZapUserSetCard -> ZapUserSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is LikeSetCard -> LikeSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is BoostSetCard -> BoostSetCompose(
|
||||
item,
|
||||
isInnerNote = false,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is MultiSetCard -> MultiSetCompose(
|
||||
item,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is BadgeCard -> BadgeCompose(
|
||||
item,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController,
|
||||
routeForLastRead = routeForLastRead
|
||||
)
|
||||
is MessageSetCard -> MessageSetCompose(
|
||||
messageSetCard = item,
|
||||
routeForLastRead = routeForLastRead,
|
||||
accountViewModel = accountViewModel,
|
||||
navController = navController
|
||||
)
|
||||
}
|
||||
}
|
||||
Log.d("Time", "${item.javaClass.simpleName} Feed in $elapsed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ fun NoteMaster(
|
||||
})
|
||||
) {
|
||||
NoteAuthorPicture(
|
||||
note = baseNote,
|
||||
baseNote = baseNote,
|
||||
navController = navController,
|
||||
userAccount = account.userProfile(),
|
||||
size = 55.dp
|
||||
|
||||
Reference in New Issue
Block a user