mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-04-10 21:09:40 +02:00
Minor updates to remember states in composition
This commit is contained in:
parent
eaae672a30
commit
6a7d6a843d
@ -143,27 +143,46 @@ private fun RenderRegular(
|
||||
}
|
||||
}
|
||||
|
||||
val paragraphs = remember(content) {
|
||||
content.split('\n').toImmutableList()
|
||||
}
|
||||
|
||||
// FlowRow doesn't work well with paragraphs. So we need to split them
|
||||
content.split('\n').forEach { paragraph ->
|
||||
FlowRow() {
|
||||
val s = remember(paragraph) {
|
||||
if (isArabic(paragraph)) {
|
||||
paragraph.trim().split(' ').reversed()
|
||||
} else {
|
||||
paragraph.trim().split(' ')
|
||||
}
|
||||
}
|
||||
s.forEach { word: String ->
|
||||
RenderWord(
|
||||
word,
|
||||
state,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
tags
|
||||
)
|
||||
}
|
||||
paragraphs.forEach { paragraph ->
|
||||
RenderParagraph(paragraph, state, canPreview, backgroundColor, accountViewModel, nav, tags)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
private fun RenderParagraph(
|
||||
paragraph: String,
|
||||
state: RichTextViewerState,
|
||||
canPreview: Boolean,
|
||||
backgroundColor: Color,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit,
|
||||
tags: ImmutableListOfLists<String>
|
||||
) {
|
||||
val s = remember(paragraph) {
|
||||
if (isArabic(paragraph)) {
|
||||
paragraph.trim().split(' ').reversed().toImmutableList()
|
||||
} else {
|
||||
paragraph.trim().split(' ').toImmutableList()
|
||||
}
|
||||
}
|
||||
|
||||
FlowRow() {
|
||||
s.forEach { word: String ->
|
||||
RenderWord(
|
||||
word,
|
||||
state,
|
||||
canPreview,
|
||||
backgroundColor,
|
||||
accountViewModel,
|
||||
nav,
|
||||
tags
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -863,13 +882,14 @@ fun HashTag(word: String, nav: (String) -> Unit) {
|
||||
} ?: Text(text = "$word ")
|
||||
}
|
||||
|
||||
data class LoadedTag(val user: User?, val note: Note?, val addedChars: String)
|
||||
|
||||
@Composable
|
||||
fun TagLink(word: String, tags: ImmutableListOfLists<String>, canPreview: Boolean, backgroundColor: Color, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
var baseUserPair by remember { mutableStateOf<Pair<User, String?>?>(null) }
|
||||
var baseNotePair by remember { mutableStateOf<Pair<Note, String?>?>(null) }
|
||||
var loadedTag by remember { mutableStateOf<LoadedTag?>(null) }
|
||||
|
||||
LaunchedEffect(key1 = word) {
|
||||
if (baseUserPair == null && baseNotePair == null) {
|
||||
if (loadedTag == null) {
|
||||
launch(Dispatchers.IO) {
|
||||
val matcher = tagIndex.matcher(word)
|
||||
val (index, suffix) = try {
|
||||
@ -877,7 +897,7 @@ fun TagLink(word: String, tags: ImmutableListOfLists<String>, canPreview: Boolea
|
||||
Pair(matcher.group(1)?.toInt(), matcher.group(2) ?: "")
|
||||
} catch (e: Exception) {
|
||||
Log.w("Tag Parser", "Couldn't link tag $word", e)
|
||||
Pair(null, null)
|
||||
Pair(null, "")
|
||||
}
|
||||
|
||||
if (index != null && index >= 0 && index < tags.lists.size) {
|
||||
@ -886,11 +906,11 @@ fun TagLink(word: String, tags: ImmutableListOfLists<String>, canPreview: Boolea
|
||||
if (tag.size > 1) {
|
||||
if (tag[0] == "p") {
|
||||
LocalCache.checkGetOrCreateUser(tag[1])?.let {
|
||||
baseUserPair = Pair(it, suffix)
|
||||
loadedTag = LoadedTag(it, null, suffix)
|
||||
}
|
||||
} else if (tag[0] == "e" || tag[0] == "a") {
|
||||
LocalCache.checkGetOrCreateNote(tag[1])?.let {
|
||||
baseNotePair = Pair(it, suffix)
|
||||
loadedTag = LoadedTag(null, it, suffix)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -899,55 +919,80 @@ fun TagLink(word: String, tags: ImmutableListOfLists<String>, canPreview: Boolea
|
||||
}
|
||||
}
|
||||
|
||||
baseUserPair?.let {
|
||||
val innerUserState by it.first.live().metadata.observeAsState()
|
||||
val displayName = remember(innerUserState) {
|
||||
innerUserState?.user?.toBestDisplayName() ?: ""
|
||||
}
|
||||
val route = remember(innerUserState) {
|
||||
"User/${it.first.pubkeyHex}"
|
||||
}
|
||||
val userTags = remember(innerUserState) {
|
||||
innerUserState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists()
|
||||
}
|
||||
|
||||
CreateClickableTextWithEmoji(
|
||||
clickablePart = displayName,
|
||||
suffix = remember { "${it.second} " },
|
||||
tags = userTags,
|
||||
route = route,
|
||||
nav = nav
|
||||
)
|
||||
}
|
||||
|
||||
baseNotePair?.let {
|
||||
if (canPreview) {
|
||||
NoteCompose(
|
||||
baseNote = it.first,
|
||||
accountViewModel = accountViewModel,
|
||||
modifier = Modifier
|
||||
.padding(top = 2.dp, bottom = 0.dp, start = 0.dp, end = 0.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(shape = RoundedCornerShape(15.dp))
|
||||
.border(
|
||||
1.dp,
|
||||
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
|
||||
RoundedCornerShape(15.dp)
|
||||
),
|
||||
parentBackgroundColor = backgroundColor,
|
||||
isQuotedNote = true,
|
||||
nav = nav
|
||||
)
|
||||
it.second?.ifBlank { null }?.let {
|
||||
Text(text = "$it ")
|
||||
if (loadedTag == null) {
|
||||
Text(
|
||||
text = remember {
|
||||
"$word "
|
||||
}
|
||||
} else {
|
||||
ClickableNoteTag(it.first, nav)
|
||||
Text(text = "${it.second} ")
|
||||
)
|
||||
} else {
|
||||
loadedTag?.user?.let {
|
||||
DisplayUserFromTag(it, loadedTag?.addedChars ?: "", nav)
|
||||
}
|
||||
}
|
||||
|
||||
if (baseNotePair == null && baseUserPair == null) {
|
||||
Text(text = "$word ")
|
||||
loadedTag?.note?.let {
|
||||
DisplayNoteFromTag(it, loadedTag?.addedChars ?: "", canPreview, accountViewModel, backgroundColor, nav)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DisplayNoteFromTag(
|
||||
baseNote: Note,
|
||||
addedChars: String,
|
||||
canPreview: Boolean,
|
||||
accountViewModel: AccountViewModel,
|
||||
backgroundColor: Color,
|
||||
nav: (String) -> Unit
|
||||
) {
|
||||
if (canPreview) {
|
||||
NoteCompose(
|
||||
baseNote = baseNote,
|
||||
accountViewModel = accountViewModel,
|
||||
modifier = Modifier
|
||||
.padding(top = 2.dp, bottom = 0.dp, start = 0.dp, end = 0.dp)
|
||||
.fillMaxWidth()
|
||||
.clip(shape = RoundedCornerShape(15.dp))
|
||||
.border(
|
||||
1.dp,
|
||||
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
|
||||
RoundedCornerShape(15.dp)
|
||||
),
|
||||
parentBackgroundColor = backgroundColor,
|
||||
isQuotedNote = true,
|
||||
nav = nav
|
||||
)
|
||||
addedChars.ifBlank { null }?.let {
|
||||
Text(text = remember { "$it " })
|
||||
}
|
||||
} else {
|
||||
ClickableNoteTag(baseNote, nav)
|
||||
Text(text = remember { "$addedChars " })
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DisplayUserFromTag(
|
||||
baseUser: User,
|
||||
addedChars: String,
|
||||
nav: (String) -> Unit
|
||||
) {
|
||||
val innerUserState by baseUser.live().metadata.observeAsState()
|
||||
val displayName = remember(innerUserState) {
|
||||
innerUserState?.user?.toBestDisplayName() ?: ""
|
||||
}
|
||||
val route = remember(innerUserState) {
|
||||
"User/${baseUser.pubkeyHex}"
|
||||
}
|
||||
val userTags = remember(innerUserState) {
|
||||
innerUserState?.user?.info?.latestMetadata?.tags?.toImmutableListOfLists()
|
||||
}
|
||||
|
||||
CreateClickableTextWithEmoji(
|
||||
clickablePart = displayName,
|
||||
suffix = remember { "$addedChars " },
|
||||
tags = userTags,
|
||||
route = route,
|
||||
nav = nav
|
||||
)
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ abstract class AdditiveFeedFilter<T> : FeedFilter<T>() {
|
||||
}
|
||||
}
|
||||
|
||||
Log.d("Time", "${this.javaClass.simpleName} Additive Feed in $elapsed with ${feed.size} objects")
|
||||
// Log.d("Time", "${this.javaClass.simpleName} Additive Feed in $elapsed with ${feed.size} objects")
|
||||
return feed
|
||||
}
|
||||
}
|
||||
|
@ -65,12 +65,10 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
val baseNote = remember { multiSetCard.note }
|
||||
|
||||
var popupExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
var isNew by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(key1 = multiSetCard.createdAt()) {
|
||||
LaunchedEffect(key1 = multiSetCard) {
|
||||
launch(Dispatchers.IO) {
|
||||
val newIsNew = multiSetCard.maxCreatedAt > NotificationCache.load(routeForLastRead)
|
||||
|
||||
@ -85,10 +83,14 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
|
||||
val primaryColor = MaterialTheme.colors.newItemBackgroundColor
|
||||
val defaultBackgroundColor = MaterialTheme.colors.background
|
||||
|
||||
val backgroundColor = if (isNew) {
|
||||
primaryColor.compositeOver(defaultBackgroundColor)
|
||||
} else {
|
||||
defaultBackgroundColor
|
||||
val backgroundColor by remember(isNew) {
|
||||
derivedStateOf {
|
||||
if (isNew) {
|
||||
primaryColor.compositeOver(defaultBackgroundColor)
|
||||
} else {
|
||||
defaultBackgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val columnModifier = Modifier
|
||||
@ -332,7 +334,7 @@ private fun AuthorPictureAndComment(
|
||||
Box(modifier = remember { Modifier.size(35.dp) }, contentAlignment = Alignment.BottomCenter) {
|
||||
FastNoteAuthorPicture(
|
||||
author = author,
|
||||
size = 35.dp,
|
||||
size = remember { 35.dp },
|
||||
accountViewModel = accountViewModel,
|
||||
pictureModifier = authorPictureModifier
|
||||
)
|
||||
@ -380,10 +382,10 @@ fun AuthorGallery(
|
||||
nav: (String) -> Unit,
|
||||
accountViewModel: AccountViewModel
|
||||
) {
|
||||
Column(modifier = Modifier.padding(start = 10.dp)) {
|
||||
Column(modifier = remember { Modifier.padding(start = 10.dp) }) {
|
||||
FlowRow() {
|
||||
authorNotes.forEach { note ->
|
||||
Box(Modifier.size(35.dp)) {
|
||||
Box(remember { Modifier.size(35.dp) }) {
|
||||
NotePictureAndComment(note, backgroundColor, nav, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,6 @@ import java.io.File
|
||||
import java.math.BigDecimal
|
||||
import java.net.URL
|
||||
import java.util.Locale
|
||||
import kotlin.time.ExperimentalTime
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
@ -331,20 +330,21 @@ private fun WatchForReports(
|
||||
onChange: (Boolean, Boolean, Set<Note>) -> Unit
|
||||
) {
|
||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||
val account = remember(accountState) { accountState?.account } ?: return
|
||||
|
||||
val noteReportsState by note.live().reports.observeAsState()
|
||||
val noteForReports = remember(noteReportsState) { noteReportsState?.note } ?: return
|
||||
|
||||
LaunchedEffect(key1 = noteReportsState, key2 = accountState) {
|
||||
launch(Dispatchers.Default) {
|
||||
account.userProfile().let { loggedIn ->
|
||||
val newCanPreview = note.author?.pubkeyHex == loggedIn.pubkeyHex ||
|
||||
(note.author?.let { loggedIn.isFollowingCached(it) } ?: true) ||
|
||||
!(noteForReports.hasAnyReports())
|
||||
accountState?.account?.let { loggedIn ->
|
||||
val newCanPreview = note.author?.pubkeyHex == loggedIn.userProfile().pubkeyHex ||
|
||||
(note.author?.let { loggedIn.userProfile().isFollowingCached(it) } ?: true) ||
|
||||
noteReportsState?.note?.hasAnyReports() != true
|
||||
|
||||
val newIsAcceptable = account.isAcceptable(noteForReports)
|
||||
val newRelevantReports = account.getRelevantReports(noteForReports)
|
||||
val newIsAcceptable = noteReportsState?.note?.let {
|
||||
loggedIn.isAcceptable(it)
|
||||
} ?: true
|
||||
val newRelevantReports = noteReportsState?.note?.let {
|
||||
loggedIn.getRelevantReports(it)
|
||||
} ?: emptySet()
|
||||
|
||||
onChange(newIsAcceptable, newCanPreview, newRelevantReports)
|
||||
}
|
||||
@ -1489,11 +1489,11 @@ private fun FirstUserInfoRow(
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
if (showAuthorPicture) {
|
||||
NoteAuthorPicture(baseNote, nav, accountViewModel, 25.dp)
|
||||
NoteAuthorPicture(baseNote, nav, accountViewModel, remember { 25.dp })
|
||||
Spacer(padding)
|
||||
NoteUsernameDisplay(baseNote, Modifier.weight(1f))
|
||||
NoteUsernameDisplay(baseNote, remember { Modifier.weight(1f) })
|
||||
} else {
|
||||
NoteUsernameDisplay(baseNote, Modifier.weight(1f))
|
||||
NoteUsernameDisplay(baseNote, remember { Modifier.weight(1f) })
|
||||
}
|
||||
|
||||
if (eventNote is RepostEvent) {
|
||||
@ -1560,7 +1560,6 @@ fun TimeAgo(time: Long) {
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
@Composable
|
||||
private fun DrawAuthorImages(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||
val baseChannelHex = remember { baseNote.channelHex() }
|
||||
@ -1670,7 +1669,7 @@ private fun RepostNoteAuthorPicture(
|
||||
baseNote = it,
|
||||
nav = nav,
|
||||
accountViewModel = accountViewModel,
|
||||
size = 30.dp,
|
||||
size = remember { 30.dp },
|
||||
pictureModifier = Modifier.border(
|
||||
2.dp,
|
||||
MaterialTheme.colors.background,
|
||||
@ -2511,6 +2510,8 @@ fun UserPicture(
|
||||
.clip(shape = CircleShape)
|
||||
}
|
||||
|
||||
val myIconSize = remember(size) { size.div(3.5f) }
|
||||
|
||||
Box(myBoxModifier, contentAlignment = TopEnd) {
|
||||
RobohashAsyncImageProxy(
|
||||
robot = userHex,
|
||||
@ -2521,7 +2522,7 @@ fun UserPicture(
|
||||
modifier = myImageModifier.background(MaterialTheme.colors.background)
|
||||
)
|
||||
|
||||
ObserveAndDisplayFollowingMark(userHex, size.div(3.5f), accountViewModel)
|
||||
ObserveAndDisplayFollowingMark(userHex, myIconSize, accountViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user