Moves the recomposition due to background color change to each compose node.

This commit is contained in:
Vitor Pamplona 2023-06-09 16:35:56 -04:00
parent 1efc4c91e2
commit bf6bc5ba68
15 changed files with 343 additions and 256 deletions

View File

@ -303,10 +303,15 @@ fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = n
UrlPreview(myUrlPreview, myUrlPreview)
}
} else if (startsWithNIP19Scheme(myUrlPreview)) {
val bgColor = MaterialTheme.colors.background
val backgroundColor = remember {
mutableStateOf(bgColor)
}
BechLink(
myUrlPreview,
true,
MaterialTheme.colors.background,
backgroundColor,
accountViewModel,
nav
)

View File

@ -12,6 +12,7 @@ import androidx.compose.material.ButtonDefaults
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -19,6 +20,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
@ -37,7 +39,7 @@ fun ExpandableRichTextViewer(
canPreview: Boolean,
modifier: Modifier,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -79,14 +81,16 @@ fun ExpandableRichTextViewer(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundColor.copy(alpha = 0f),
backgroundColor
.drawBehind {
drawRect(
Brush.verticalGradient(
colors = listOf(
backgroundColor.value.copy(alpha = 0f),
backgroundColor.value
)
)
)
)
}
) {
ShowMoreButton() {
showFullText = !showFullText

View File

@ -100,7 +100,7 @@ fun RichTextViewer(
canPreview: Boolean,
modifier: Modifier,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -129,7 +129,7 @@ private fun RenderRegular(
content: String,
tags: ImmutableListOfLists<String>,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -159,7 +159,7 @@ private fun RenderParagraph(
paragraph: String,
state: RichTextViewerState,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
tags: ImmutableListOfLists<String>
@ -234,7 +234,7 @@ private fun RenderWord(
word: String,
state: RichTextViewerState,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
tags: ImmutableListOfLists<String>
@ -288,7 +288,7 @@ private fun RenderWordWithoutPreview(
word: String,
state: RichTextViewerState,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -321,7 +321,7 @@ private fun RenderWordWithPreview(
word: String,
state: RichTextViewerState,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -402,7 +402,7 @@ fun RenderCustomEmoji(word: String, state: RichTextViewerState) {
}
@Composable
private fun RenderContentAsMarkdown(content: String, backgroundColor: Color, tags: ImmutableListOfLists<String>?, nav: (String) -> Unit) {
private fun RenderContentAsMarkdown(content: String, backgroundColor: MutableState<Color>, tags: ImmutableListOfLists<String>?, nav: (String) -> Unit) {
val myMarkDownStyle = richTextDefaults.copy(
codeBlockStyle = richTextDefaults.codeBlockStyle?.copy(
textStyle = TextStyle(
@ -421,7 +421,7 @@ private fun RenderContentAsMarkdown(content: String, backgroundColor: Color, tag
.background(
MaterialTheme.colors.onSurface
.copy(alpha = 0.05f)
.compositeOver(backgroundColor)
.compositeOver(backgroundColor.value)
)
),
stringStyle = richTextDefaults.stringStyle?.copy(
@ -432,7 +432,7 @@ private fun RenderContentAsMarkdown(content: String, backgroundColor: Color, tag
fontFamily = FontFamily.Monospace,
fontSize = 14.sp,
background = MaterialTheme.colors.onSurface.copy(alpha = 0.22f)
.compositeOver(backgroundColor)
.compositeOver(backgroundColor.value)
)
)
)
@ -722,7 +722,7 @@ fun startsWithNIP19Scheme(word: String): Boolean {
data class LoadedBechLink(val baseNote: Note?, val nip19: Nip19.Return)
@Composable
fun BechLink(word: String, canPreview: Boolean, backgroundColor: Color, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
fun BechLink(word: String, canPreview: Boolean, backgroundColor: MutableState<Color>, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
var loadedLink by remember { mutableStateOf<LoadedBechLink?>(null) }
LaunchedEffect(key1 = word) {
@ -763,11 +763,10 @@ fun BechLink(word: String, canPreview: Boolean, backgroundColor: Color, accountV
private fun DisplayFullNote(
it: Note,
accountViewModel: AccountViewModel,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
loadedLink: LoadedBechLink
) {
println("AAA: Display Full Note")
val borderColor = MaterialTheme.colors.onSurface.copy(alpha = 0.12f)
val modifier = remember {
@ -886,7 +885,7 @@ fun HashTag(word: String, nav: (String) -> Unit) {
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) {
fun TagLink(word: String, tags: ImmutableListOfLists<String>, canPreview: Boolean, backgroundColor: MutableState<Color>, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
var loadedTag by remember { mutableStateOf<LoadedTag?>(null) }
LaunchedEffect(key1 = word) {
@ -943,7 +942,7 @@ private fun DisplayNoteFromTag(
addedChars: String,
canPreview: Boolean,
accountViewModel: AccountViewModel,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit
) {
if (canPreview) {

View File

@ -1,7 +1,6 @@
package com.vitorpamplona.amethyst.ui.note
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -27,6 +26,8 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@ -54,25 +55,33 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL
if (note == null) {
BlankNote(Modifier, isInnerNote)
} else {
var isNew by remember { mutableStateOf<Boolean>(false) }
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
val newItemColor = MaterialTheme.colors.newItemBackgroundColor
LaunchedEffect(key1 = likeSetCard) {
scope.launch(Dispatchers.IO) {
isNew = likeSetCard.createdAt() > NotificationCache.load(routeForLastRead)
val isNew = likeSetCard.createdAt() > NotificationCache.load(routeForLastRead)
NotificationCache.markAsRead(routeForLastRead, likeSetCard.createdAt())
}
}
val backgroundColor = if (isNew) {
MaterialTheme.colors.newItemBackgroundColor.compositeOver(MaterialTheme.colors.background)
} else {
MaterialTheme.colors.background
val newBackgroundColor = if (isNew) {
newItemColor.compositeOver(defaultBackgroundColor)
} else {
defaultBackgroundColor
}
if (backgroundColor.value != newBackgroundColor) {
backgroundColor.value = newBackgroundColor
}
}
}
Column(
modifier = Modifier
.background(backgroundColor)
.drawBehind {
drawRect(backgroundColor.value)
}
.combinedClickable(
onClick = {
scope.launch {

View File

@ -27,6 +27,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -78,7 +79,7 @@ fun ChatroomMessageCompose(
baseNote: Note,
routeForLastRead: String?,
innerQuote: Boolean = false,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
onWantsToReply: (Note) -> Unit
@ -143,22 +144,30 @@ fun ChatroomMessageCompose(
onClick = { showHiddenNote = true }
)
} else {
val backgroundBubbleColor: Color
val alignment: Arrangement.Horizontal
val shape: Shape
val loggedInColors = MaterialTheme.colors.primary.copy(alpha = 0.32f)
val otherColors = MaterialTheme.colors.onSurface.copy(alpha = 0.12f)
val defaultBackground = MaterialTheme.colors.background
if (note.author == loggedIn) {
backgroundBubbleColor = MaterialTheme.colors.primary.copy(alpha = 0.32f)
.compositeOver(parentBackgroundColor ?: MaterialTheme.colors.background)
alignment = Arrangement.End
shape = ChatBubbleShapeMe
} else {
backgroundBubbleColor = MaterialTheme.colors.onSurface.copy(alpha = 0.12f)
.compositeOver(parentBackgroundColor ?: MaterialTheme.colors.background)
alignment = Arrangement.Start
shape = ChatBubbleShapeThem
val backgroundBubbleColor = remember {
if (note.author == loggedIn) {
mutableStateOf(loggedInColors.compositeOver(parentBackgroundColor?.value ?: defaultBackground))
} else {
mutableStateOf(otherColors.compositeOver(parentBackgroundColor?.value ?: defaultBackground))
}
}
val alignment: Arrangement.Horizontal = remember {
if (note.author == loggedIn) {
Arrangement.End
} else {
Arrangement.Start
}
}
val shape: Shape = remember {
if (note.author == loggedIn) {
ChatBubbleShapeMe
} else {
ChatBubbleShapeThem
}
}
val scope = rememberCoroutineScope()
@ -206,7 +215,7 @@ fun ChatroomMessageCompose(
}
) {
Surface(
color = backgroundBubbleColor,
color = backgroundBubbleColor.value,
shape = shape,
modifier = Modifier
.combinedClickable(
@ -361,7 +370,7 @@ fun ChatTimeAgo(time: Long) {
private fun RenderRegularTextNote(
note: Note,
canPreview: Boolean,
backgroundBubbleColor: Color,
backgroundBubbleColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {

View File

@ -23,6 +23,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Bolt
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -33,6 +34,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.res.painterResource
@ -66,35 +68,33 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
var popupExpanded by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope()
var isNew by remember { mutableStateOf(false) }
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
val newItemColor = MaterialTheme.colors.newItemBackgroundColor
LaunchedEffect(key1 = multiSetCard) {
launch(Dispatchers.IO) {
val newIsNew = multiSetCard.maxCreatedAt > NotificationCache.load(routeForLastRead)
val isNew = multiSetCard.maxCreatedAt > NotificationCache.load(routeForLastRead)
NotificationCache.markAsRead(routeForLastRead, multiSetCard.maxCreatedAt)
if (newIsNew != isNew) {
isNew = newIsNew
}
}
}
val primaryColor = MaterialTheme.colors.newItemBackgroundColor
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor by remember(isNew) {
derivedStateOf {
if (isNew) {
primaryColor.compositeOver(defaultBackgroundColor)
val newBackgroundColor = if (isNew) {
newItemColor.compositeOver(defaultBackgroundColor)
} else {
defaultBackgroundColor
}
if (backgroundColor.value != newBackgroundColor) {
backgroundColor.value = newBackgroundColor
}
}
}
val columnModifier = Modifier
.background(backgroundColor)
.drawBehind {
drawRect(backgroundColor.value)
}
.padding(
start = 12.dp,
end = 12.dp,
@ -152,7 +152,7 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun
@Composable
fun RenderLikeGallery(
likeEvents: ImmutableList<Note>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -183,7 +183,7 @@ fun RenderLikeGallery(
@Composable
fun RenderZapGallery(
zapEvents: ImmutableMap<Note, Note?>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -214,7 +214,7 @@ fun RenderZapGallery(
@Composable
fun RenderBoostGallery(
boostEvents: ImmutableList<Note>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -250,7 +250,7 @@ fun RenderBoostGallery(
@Composable
fun AuthorGalleryZaps(
authorNotes: ImmutableMap<Note, Note?>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -267,7 +267,7 @@ fun AuthorGalleryZaps(
private fun AuthorPictureAndComment(
zapRequest: Note,
zapEvent: Note?,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -315,7 +315,7 @@ private fun AuthorPictureAndComment(
comment: String?,
amount: String?,
route: String,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -378,7 +378,7 @@ private fun AuthorPictureAndComment(
@Composable
fun AuthorGallery(
authorNotes: ImmutableList<Note>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {
@ -396,7 +396,7 @@ fun AuthorGallery(
@Composable
private fun NotePictureAndComment(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit,
accountViewModel: AccountViewModel
) {

View File

@ -47,6 +47,7 @@ import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
@ -60,6 +61,7 @@ import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.Alignment.Companion.TopEnd
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
@ -145,6 +147,7 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
import com.vitorpamplona.amethyst.ui.theme.Following
import com.vitorpamplona.amethyst.ui.theme.QuoteBorder
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
import com.vitorpamplona.amethyst.ui.theme.replyBackground
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentListOf
@ -171,7 +174,7 @@ fun NoteCompose(
unPackReply: Boolean = true,
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -217,7 +220,7 @@ fun CheckHiddenNoteCompose(
unPackReply: Boolean = true,
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -265,7 +268,7 @@ fun LoadedNoteCompose(
unPackReply: Boolean = true,
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -366,7 +369,7 @@ fun NormalNote(
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
canPreview: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -400,7 +403,6 @@ fun NormalNote(
}
@Composable
@OptIn(ExperimentalFoundationApi::class)
private fun CheckNewAndRenderNote(
baseNote: Note,
routeForLastRead: String? = null,
@ -411,13 +413,15 @@ private fun CheckNewAndRenderNote(
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
canPreview: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
var isNew by remember { mutableStateOf<Boolean>(false) }
val newItemColor = MaterialTheme.colors.newItemBackgroundColor
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
LaunchedEffect(key1 = routeForLastRead) {
LaunchedEffect(key1 = routeForLastRead, key2 = parentBackgroundColor?.value) {
launch(Dispatchers.IO) {
routeForLastRead?.let {
val lastTime = NotificationCache.load(it)
@ -426,44 +430,52 @@ private fun CheckNewAndRenderNote(
if (createdAt != null) {
NotificationCache.markAsRead(it, createdAt)
val newIsNew = createdAt > lastTime
if (newIsNew != isNew) {
isNew = newIsNew
val isNew = createdAt > lastTime
val newBackgroundColor = if (isNew) {
if (parentBackgroundColor != null) {
newItemColor.compositeOver(parentBackgroundColor.value)
} else {
newItemColor.compositeOver(defaultBackgroundColor)
}
} else {
parentBackgroundColor?.value ?: defaultBackgroundColor
}
if (newBackgroundColor != backgroundColor.value) {
backgroundColor.value = newBackgroundColor
}
}
} ?: run {
val newBackgroundColor = parentBackgroundColor?.value ?: defaultBackgroundColor
if (newBackgroundColor != backgroundColor.value) {
backgroundColor.value = newBackgroundColor
}
}
}
}
val primaryColor = MaterialTheme.colors.newItemBackgroundColor
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember(isNew, parentBackgroundColor) {
if (isNew) {
if (parentBackgroundColor != null) {
primaryColor.compositeOver(parentBackgroundColor)
} else {
primaryColor.compositeOver(defaultBackgroundColor)
}
} else {
parentBackgroundColor ?: defaultBackgroundColor
val updatedModifier = remember(backgroundColor.value) {
modifier.drawBehind {
drawRect(backgroundColor.value)
}
}
LongPressToQuickAction(baseNote = baseNote, accountViewModel = accountViewModel) { showPopup ->
RenderNoteWithReactions(
backgroundColor,
showPopup,
modifier,
baseNote,
accountViewModel,
nav,
isBoostedNote,
isQuotedNote,
addMarginTop,
unPackReply,
makeItShort,
canPreview
modifier = updatedModifier,
backgroundColor = backgroundColor,
baseNote = baseNote,
isBoostedNote = isBoostedNote,
isQuotedNote = isQuotedNote,
addMarginTop = addMarginTop,
unPackReply = unPackReply,
makeItShort = makeItShort,
canPreview = canPreview,
accountViewModel = accountViewModel,
showPopup = showPopup,
nav = nav
)
}
}
@ -471,22 +483,22 @@ private fun CheckNewAndRenderNote(
@Composable
@OptIn(ExperimentalFoundationApi::class)
private fun RenderNoteWithReactions(
backgroundColor: Color,
showPopup: () -> Unit,
modifier: Modifier,
baseNote: Note,
accountViewModel: AccountViewModel,
nav: (String) -> Unit,
backgroundColor: MutableState<Color>,
modifier: Modifier,
isBoostedNote: Boolean,
isQuotedNote: Boolean,
addMarginTop: Boolean,
unPackReply: Boolean,
makeItShort: Boolean,
canPreview: Boolean
canPreview: Boolean,
accountViewModel: AccountViewModel,
showPopup: () -> Unit,
nav: (String) -> Unit
) {
val scope = rememberCoroutineScope()
val columnModifier = remember(backgroundColor, showPopup) {
val columnModifier = remember(showPopup) {
modifier
.combinedClickable(
onClick = {
@ -498,7 +510,6 @@ private fun RenderNoteWithReactions(
},
onLongClick = showPopup
)
.background(backgroundColor)
}
val notBoostedNorQuote by remember {
@ -531,24 +542,24 @@ private fun RenderNoteWithReactions(
}
NoteBody(
baseNote,
isQuotedNote,
unPackReply,
makeItShort,
canPreview,
showSecondRow,
backgroundColor,
accountViewModel,
nav
baseNote = baseNote,
showAuthorPicture = isQuotedNote,
unPackReply = unPackReply,
makeItShort = makeItShort,
canPreview = canPreview,
showSecondRow = showSecondRow,
backgroundColor = backgroundColor,
accountViewModel = accountViewModel,
nav = nav
)
}
if (!makeItShort && baseNote.event !is RepostEvent) {
ReactionsRow(
baseNote,
notBoostedNorQuote,
accountViewModel,
nav
baseNote = baseNote,
showReactionDetail = notBoostedNorQuote,
accountViewModel = accountViewModel,
nav = nav
)
} else {
if (!isBoostedNote && baseNote.event !is RepostEvent) {
@ -572,7 +583,7 @@ private fun NoteBody(
makeItShort: Boolean = false,
canPreview: Boolean = true,
showSecondRow: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -618,7 +629,7 @@ private fun NoteBody(
@Composable
private fun RenderNoteRow(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
makeItShort: Boolean,
canPreview: Boolean,
accountViewModel: AccountViewModel,
@ -651,11 +662,11 @@ private fun RenderNoteRow(
}
is PeopleListEvent -> {
RenderPeopleList(baseNote, backgroundColor, accountViewModel, nav)
DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav)
}
is RelaySetEvent -> {
RelaySetList(baseNote, backgroundColor, accountViewModel, nav)
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
}
is AudioTrackEvent -> {
@ -733,7 +744,7 @@ private fun RenderTextEvent(
note: Note,
makeItShort: Boolean,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -781,7 +792,7 @@ private fun RenderPoll(
note: Note,
makeItShort: Boolean,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -971,11 +982,15 @@ fun RenderAppDefinition(
modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
) {
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() }
val bgColor = MaterialTheme.colors.background
val backgroundColor = remember {
mutableStateOf(bgColor)
}
TranslatableRichTextViewer(
content = it,
canPreview = false,
tags = tags,
backgroundColor = MaterialTheme.colors.background,
backgroundColor = backgroundColor,
accountViewModel = accountViewModel,
nav = nav
)
@ -991,7 +1006,7 @@ private fun RenderHighlight(
note: Note,
makeItShort: Boolean,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1022,7 +1037,7 @@ private fun RenderPrivateMessage(
note: Note,
makeItShort: Boolean,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1086,30 +1101,10 @@ private fun RenderPrivateMessage(
}
}
@Composable
fun RelaySetList(
baseNote: Note,
backgroundColor: Color,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
DisplayRelaySet(baseNote, backgroundColor, accountViewModel, nav)
}
@Composable
fun RenderPeopleList(
baseNote: Note,
backgroundColor: Color,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav)
}
@Composable
fun DisplayRelaySet(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1195,14 +1190,16 @@ fun DisplayRelaySet(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundColor.copy(alpha = 0f),
backgroundColor
.drawBehind {
drawRect(
Brush.verticalGradient(
colors = listOf(
backgroundColor.value.copy(alpha = 0f),
backgroundColor.value
)
)
)
)
}
) {
ShowMoreButton {
expanded = !expanded
@ -1243,7 +1240,7 @@ private fun RelayOptionsAction(
@Composable
fun DisplayPeopleList(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1302,14 +1299,16 @@ fun DisplayPeopleList(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundColor.copy(alpha = 0f),
backgroundColor
.drawBehind {
drawRect(
Brush.verticalGradient(
colors = listOf(
backgroundColor.value.copy(alpha = 0f),
backgroundColor.value
)
)
)
)
}
) {
Button(
modifier = Modifier.padding(top = 10.dp),
@ -1332,7 +1331,7 @@ fun DisplayPeopleList(
@Composable
private fun RenderBadgeAward(
note: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1393,7 +1392,7 @@ private fun RenderBadgeAward(
@Composable
private fun RenderReaction(
note: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1421,7 +1420,7 @@ private fun RenderReaction(
@Composable
private fun RenderRepost(
note: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1445,7 +1444,7 @@ private fun RenderRepost(
@Composable
private fun RenderPinListEvent(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1456,7 +1455,7 @@ private fun RenderPinListEvent(
@Composable
fun PinListHeader(
baseNote: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1517,14 +1516,16 @@ fun PinListHeader(
modifier = Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundColor.copy(alpha = 0f),
backgroundColor
.drawBehind {
drawRect(
Brush.verticalGradient(
colors = listOf(
backgroundColor.value.copy(alpha = 0f),
backgroundColor.value
)
)
)
)
}
) {
Button(
modifier = Modifier.padding(top = 10.dp),
@ -1568,7 +1569,7 @@ private fun RenderLongFormContent(
@Composable
private fun RenderReport(
note: Note,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -1629,54 +1630,86 @@ private fun RenderReport(
private fun ReplyRow(
note: Note,
unPackReply: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
val noteEvent = note.event
if (noteEvent is TextNoteEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())) {
val replyingDirectlyTo = remember {
note.replyTo?.lastOrNull()
val showReply by remember {
derivedStateOf {
noteEvent is TextNoteEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())
}
}
val showChannelReply by remember {
derivedStateOf {
noteEvent is ChannelMessageEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())
}
}
if (showReply) {
val replyingDirectlyTo = remember { note.replyTo?.lastOrNull() }
if (replyingDirectlyTo != null && unPackReply) {
NoteCompose(
baseNote = replyingDirectlyTo,
isQuotedNote = true,
modifier = Modifier
.padding(top = 5.dp)
.fillMaxWidth()
.clip(shape = QuoteBorder)
.border(
1.dp,
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
QuoteBorder
),
unPackReply = false,
makeItShort = true,
parentBackgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.05f)
.compositeOver(backgroundColor),
accountViewModel = accountViewModel,
nav = nav
)
ReplyNoteComposition(replyingDirectlyTo, backgroundColor, accountViewModel, nav)
Spacer(modifier = Modifier.height(5.dp))
} else {
// ReplyInformation(note.replyTo, noteEvent.mentions(), accountViewModel, nav)
}
Spacer(modifier = Modifier.height(5.dp))
} else if (noteEvent is ChannelMessageEvent && (note.replyTo != null || noteEvent.hasAnyTaggedUser())) {
} else if (showChannelReply) {
val channelHex = note.channelHex()
channelHex?.let {
val replies = remember { note.replyTo?.toImmutableList() }
val mentions = remember { noteEvent.mentions().toImmutableList() }
val mentions = remember { (note.event as? ChannelMessageEvent)?.mentions()?.toImmutableList() ?: persistentListOf() }
ReplyInformationChannel(replies, mentions, it, accountViewModel, nav)
Spacer(modifier = Modifier.height(5.dp))
}
Spacer(modifier = Modifier.height(5.dp))
}
}
@Composable
private fun ReplyNoteComposition(
replyingDirectlyTo: Note,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
val replyBackgroundColor = remember {
mutableStateOf(backgroundColor.value)
}
val defaultReplyBackground = MaterialTheme.colors.replyBackground
LaunchedEffect(key1 = backgroundColor.value, key2 = defaultReplyBackground) {
launch(Dispatchers.IO) {
val newReplyBackgroundColor =
defaultReplyBackground.compositeOver(backgroundColor.value)
if (replyBackgroundColor.value != newReplyBackgroundColor) {
replyBackgroundColor.value = newReplyBackgroundColor
}
}
}
NoteCompose(
baseNote = replyingDirectlyTo,
isQuotedNote = true,
modifier = Modifier
.padding(top = 5.dp)
.fillMaxWidth()
.clip(shape = QuoteBorder)
.border(
1.dp,
MaterialTheme.colors.onSurface.copy(alpha = 0.12f),
QuoteBorder
),
unPackReply = false,
makeItShort = true,
parentBackgroundColor = replyBackgroundColor,
accountViewModel = accountViewModel,
nav = nav
)
}
@Composable
private fun SecondUserInfoRow(
note: Note,
@ -1915,7 +1948,7 @@ fun DisplayHighlight(
url: String?,
makeItShort: Boolean,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {

View File

@ -42,7 +42,7 @@ import kotlin.math.roundToInt
fun PollNote(
baseNote: Note,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -67,7 +67,7 @@ fun PollNote(
baseNote: Note,
pollViewModel: PollNoteViewModel,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -109,7 +109,7 @@ private fun OptionNote(
baseNote: Note,
accountViewModel: AccountViewModel,
canPreview: Boolean,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
nav: (String) -> Unit
) {
val tags = remember(baseNote) {
@ -169,7 +169,7 @@ private fun RenderOptionAfterVote(
color: Color,
canPreview: Boolean,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {
@ -236,7 +236,7 @@ private fun RenderOptionBeforeVote(
description: String,
canPreview: Boolean,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {

View File

@ -173,6 +173,9 @@ private fun ReactionDetailGallery(
val boostsState by baseNote.live().boosts.observeAsState()
val reactionsState by baseNote.live().reactions.observeAsState()
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
val hasReactions by remember(zapsState, boostsState, reactionsState) {
derivedStateOf {
baseNote.zaps.isNotEmpty() ||
@ -195,7 +198,7 @@ private fun ReactionDetailGallery(
if (hasZapEvents) {
RenderZapGallery(
zapEvents,
MaterialTheme.colors.background,
backgroundColor,
nav,
accountViewModel
)
@ -204,7 +207,7 @@ private fun ReactionDetailGallery(
if (hasBoostEvents) {
RenderBoostGallery(
boostEvents,
MaterialTheme.colors.background,
backgroundColor,
nav,
accountViewModel
)
@ -213,7 +216,7 @@ private fun ReactionDetailGallery(
if (hasLikeEvents) {
RenderLikeGallery(
likeEvents,
MaterialTheme.colors.background,
backgroundColor,
nav,
accountViewModel
)

View File

@ -21,6 +21,8 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@ -35,29 +37,33 @@ import kotlinx.coroutines.launch
@Composable
fun ZapUserSetCompose(zapSetCard: ZapUserSetCard, isInnerNote: Boolean = false, routeForLastRead: String, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
var isNew by remember { mutableStateOf<Boolean>(false) }
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
val newItemColor = MaterialTheme.colors.newItemBackgroundColor
LaunchedEffect(key1 = zapSetCard.createdAt()) {
launch(Dispatchers.IO) {
val newIsNew = zapSetCard.createdAt > NotificationCache.load(routeForLastRead)
val isNew = zapSetCard.createdAt > NotificationCache.load(routeForLastRead)
NotificationCache.markAsRead(routeForLastRead, zapSetCard.createdAt)
if (newIsNew != isNew) {
isNew = newIsNew
val newBackgroundColor = if (isNew) {
newItemColor.compositeOver(defaultBackgroundColor)
} else {
defaultBackgroundColor
}
if (backgroundColor.value != newBackgroundColor) {
backgroundColor.value = newBackgroundColor
}
}
}
var backgroundColor = if (isNew) {
MaterialTheme.colors.newItemBackgroundColor.compositeOver(MaterialTheme.colors.background)
} else {
MaterialTheme.colors.background
}
Column(
modifier = Modifier
.background(backgroundColor)
.drawBehind {
drawRect(backgroundColor.value)
}
.clickable {
nav("User/${zapSetCard.user.pubkeyHex}")
}

View File

@ -19,6 +19,7 @@ import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@ -241,7 +242,7 @@ fun NoteCompose(
unPackReply: Boolean = true,
makeItShort: Boolean = false,
addMarginTop: Boolean = true,
parentBackgroundColor: Color? = null,
parentBackgroundColor: MutableState<Color>? = null,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {

View File

@ -42,7 +42,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@ -82,7 +81,7 @@ import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.ReactionsRow
import com.vitorpamplona.amethyst.ui.note.timeAgo
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.theme.newItemBackgroundColor
import com.vitorpamplona.amethyst.ui.theme.selectedNote
import kotlinx.collections.immutable.toImmutableList
import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.delay
@ -151,6 +150,11 @@ fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: A
} else {
Column() {
Row() {
val selectedNoteColor = MaterialTheme.colors.selectedNote
val background = remember {
if (item.idHex == noteId) mutableStateOf(selectedNoteColor) else null
}
NoteCompose(
item,
modifier = Modifier.drawReplyLevel(
@ -158,7 +162,7 @@ fun ThreadFeedView(noteId: String, viewModel: FeedViewModel, accountViewModel: A
MaterialTheme.colors.onSurface.copy(alpha = 0.32f),
if (item.idHex == noteId) MaterialTheme.colors.primary.copy(alpha = 0.52f) else MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
),
parentBackgroundColor = if (item.idHex == noteId) MaterialTheme.colors.newItemBackgroundColor.compositeOver(MaterialTheme.colors.background) else null,
parentBackgroundColor = background,
isBoostedNote = false,
unPackReply = false,
accountViewModel = accountViewModel,
@ -232,6 +236,9 @@ fun NoteMaster(
var popupExpanded by remember { mutableStateOf(false) }
val defaultBackgroundColor = MaterialTheme.colors.background
val backgroundColor = remember { mutableStateOf<Color>(defaultBackgroundColor) }
if (noteEvent == null) {
BlankNote()
} else if (!account.isAcceptable(noteForReports) && !showHiddenNote) {
@ -365,20 +372,20 @@ fun NoteMaster(
) {
Column() {
if (noteEvent is PeopleListEvent) {
DisplayPeopleList(baseNote, MaterialTheme.colors.background, accountViewModel, nav)
DisplayPeopleList(baseNote, backgroundColor, accountViewModel, nav)
} else if (noteEvent is AudioTrackEvent) {
AudioTrackHeader(noteEvent, accountViewModel, nav)
} else if (noteEvent is PinListEvent) {
PinListHeader(
baseNote,
MaterialTheme.colors.background,
backgroundColor,
accountViewModel,
nav
)
} else if (noteEvent is RelaySetEvent) {
DisplayRelaySet(
baseNote,
MaterialTheme.colors.background,
backgroundColor,
accountViewModel,
nav
)
@ -415,7 +422,7 @@ fun NoteMaster(
canPreview,
remember { Modifier.fillMaxWidth() },
tags,
MaterialTheme.colors.background,
backgroundColor,
accountViewModel,
nav
)

View File

@ -719,11 +719,16 @@ private fun DrawAdditionalInfo(
Row(
modifier = Modifier.padding(top = 5.dp, bottom = 5.dp)
) {
val defaultBackground = MaterialTheme.colors.background
val background = remember {
mutableStateOf(defaultBackground)
}
TranslatableRichTextViewer(
content = it,
canPreview = false,
tags = remember { ImmutableListOfLists(emptyList()) },
backgroundColor = MaterialTheme.colors.background,
backgroundColor = background,
accountViewModel = accountViewModel,
nav = nav
)

View File

@ -9,8 +9,8 @@ import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalView
@ -26,20 +26,25 @@ private val LightColorPalette = lightColors(
primaryVariant = Purple700,
secondary = Teal200,
secondaryVariant = Color(0xFFB66605)
/* Other default colors to override
background = Color.White,
surface = Color.White,
onPrimary = Color.White,
onSecondary = Color.Black,
onBackground = Color.Black,
onSurface = Color.Black,
*/
)
private val DarkNewItemBackground = DarkColorPalette.primary.copy(0.12f)
private val LightNewItemBackground = LightColorPalette.primary.copy(0.12f)
private val DarkReplyItemBackground = DarkColorPalette.onSurface.copy(alpha = 0.05f)
private val LightReplyItemBackground = LightColorPalette.onSurface.copy(alpha = 0.05f)
private val DarkSelectedNote = DarkNewItemBackground.compositeOver(DarkColorPalette.background)
private val LightSelectedNote = LightNewItemBackground.compositeOver(LightColorPalette.background)
val Colors.newItemBackgroundColor: Color
@Composable
get() = remember { if (isLight) primary.copy(0.05f) else primary.copy(0.12f) }
get() = if (isLight) LightNewItemBackground else DarkNewItemBackground
val Colors.replyBackground: Color
get() = if (isLight) LightReplyItemBackground else DarkReplyItemBackground
val Colors.selectedNote: Color
get() = if (isLight) LightSelectedNote else DarkSelectedNote
@Composable
fun AmethystTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {

View File

@ -14,6 +14,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -45,7 +46,7 @@ fun TranslatableRichTextViewer(
canPreview: Boolean,
modifier: Modifier = Modifier,
tags: ImmutableListOfLists<String>,
backgroundColor: Color,
backgroundColor: MutableState<Color>,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
) {