Better recomposition structure for ReactionsRow
This commit is contained in:
@@ -63,7 +63,6 @@ import androidx.compose.ui.window.DialogProperties
|
|||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
import com.vitorpamplona.amethyst.service.NostrSearchEventOrUserDataSource
|
||||||
@@ -78,7 +77,10 @@ import kotlinx.coroutines.launch
|
|||||||
|
|
||||||
@OptIn(ExperimentalComposeUiApi::class)
|
@OptIn(ExperimentalComposeUiApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = null, account: Account, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun NewPostView(onClose: () -> Unit, baseReplyTo: Note? = null, quote: Note? = null, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
|
val account = remember(accountState) { accountState?.account } ?: return
|
||||||
|
|
||||||
val postViewModel: NewPostViewModel = viewModel()
|
val postViewModel: NewPostViewModel = viewModel()
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|||||||
@@ -17,18 +17,17 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NewNoteButton(account: Account, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun NewNoteButton(accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
var wantsToPost by remember {
|
var wantsToPost by remember {
|
||||||
mutableStateOf(false)
|
mutableStateOf(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToPost) {
|
if (wantsToPost) {
|
||||||
NewPostView({ wantsToPost = false }, account = account, accountViewModel = accountViewModel, nav = nav)
|
NewPostView({ wantsToPost = false }, accountViewModel = accountViewModel, nav = nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
OutlinedButton(
|
OutlinedButton(
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.note
|
package com.vitorpamplona.amethyst.ui.note
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.combinedClickable
|
import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
@@ -20,6 +21,7 @@ import androidx.compose.material.CircularProgressIndicator
|
|||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.material.ProgressIndicatorDefaults
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Bolt
|
import androidx.compose.material.icons.filled.Bolt
|
||||||
@@ -56,6 +58,7 @@ import coil.request.CachePolicy
|
|||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
import com.vitorpamplona.amethyst.ui.actions.NewPostView
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange
|
||||||
@@ -68,9 +71,6 @@ import kotlin.math.roundToInt
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
|
||||||
val account = remember(accountState) { accountState?.account } ?: return
|
|
||||||
|
|
||||||
val grayTint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
val grayTint = MaterialTheme.colors.onSurface.copy(alpha = 0.32f)
|
||||||
|
|
||||||
var wantsToReplyTo by remember {
|
var wantsToReplyTo by remember {
|
||||||
@@ -82,17 +82,17 @@ fun ReactionsRow(baseNote: Note, accountViewModel: AccountViewModel, nav: (Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToReplyTo != null) {
|
if (wantsToReplyTo != null) {
|
||||||
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, null, account, accountViewModel, nav)
|
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, null, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToQuote != null) {
|
if (wantsToQuote != null) {
|
||||||
NewPostView({ wantsToQuote = null }, null, wantsToQuote, account, accountViewModel, nav)
|
NewPostView({ wantsToQuote = null }, null, wantsToQuote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
Row(verticalAlignment = CenterVertically) {
|
Row(verticalAlignment = CenterVertically) {
|
||||||
Row(verticalAlignment = CenterVertically, modifier = Modifier.weight(1f)) {
|
Row(verticalAlignment = CenterVertically, modifier = remember { Modifier.weight(1f) }) {
|
||||||
ReplyReaction(baseNote, grayTint, accountViewModel) {
|
ReplyReaction(baseNote, grayTint, accountViewModel) {
|
||||||
wantsToReplyTo = baseNote
|
wantsToReplyTo = baseNote
|
||||||
}
|
}
|
||||||
@@ -123,17 +123,6 @@ fun ReplyReaction(
|
|||||||
iconSize: Dp = 20.dp,
|
iconSize: Dp = 20.dp,
|
||||||
onPress: () -> Unit
|
onPress: () -> Unit
|
||||||
) {
|
) {
|
||||||
val repliesState by baseNote.live().replies.observeAsState()
|
|
||||||
val replies = remember(repliesState) { repliesState?.note?.replies } ?: emptySet()
|
|
||||||
|
|
||||||
val isWriteable = remember { accountViewModel.isWriteable() }
|
|
||||||
|
|
||||||
val replyCount by remember(repliesState) {
|
|
||||||
derivedStateOf {
|
|
||||||
showCount(replies.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
@@ -148,7 +137,7 @@ fun ReplyReaction(
|
|||||||
IconButton(
|
IconButton(
|
||||||
modifier = iconButtonModifier,
|
modifier = iconButtonModifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (isWriteable) {
|
if (accountViewModel.isWriteable()) {
|
||||||
onPress()
|
onPress()
|
||||||
} else {
|
} else {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -170,14 +159,26 @@ fun ReplyReaction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (showCounter) {
|
if (showCounter) {
|
||||||
Text(
|
ReplyCounter(baseNote, grayTint)
|
||||||
" $replyCount",
|
|
||||||
fontSize = 14.sp,
|
|
||||||
color = grayTint
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReplyCounter(baseNote: Note, textColor: Color) {
|
||||||
|
val repliesState by baseNote.live().replies.observeAsState()
|
||||||
|
val replyCount by remember(repliesState) {
|
||||||
|
derivedStateOf {
|
||||||
|
" " + showCount(repliesState?.note?.replies?.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = replyCount,
|
||||||
|
fontSize = 14.sp,
|
||||||
|
color = textColor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BoostReaction(
|
fun BoostReaction(
|
||||||
baseNote: Note,
|
baseNote: Note,
|
||||||
@@ -186,29 +187,6 @@ fun BoostReaction(
|
|||||||
iconSize: Dp = 20.dp,
|
iconSize: Dp = 20.dp,
|
||||||
onQuotePress: () -> Unit
|
onQuotePress: () -> Unit
|
||||||
) {
|
) {
|
||||||
val boostsState by baseNote.live().boosts.observeAsState()
|
|
||||||
val boostedNote = remember(boostsState) { boostsState?.note } ?: return
|
|
||||||
|
|
||||||
val hasBoosted by remember(boostsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
accountViewModel.hasBoosted(baseNote)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val wasBoostedByLoggedIn by remember(boostsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
boostedNote.isBoostedBy(accountViewModel.userProfile())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isWriteable = remember { accountViewModel.isWriteable() }
|
|
||||||
|
|
||||||
val boostCount by remember(boostsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
showCount(boostedNote.boosts.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
@@ -218,15 +196,11 @@ fun BoostReaction(
|
|||||||
Modifier.size(iconSize)
|
Modifier.size(iconSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
val iconModifier = remember {
|
|
||||||
Modifier.size(iconSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = iconButtonModifier,
|
modifier = iconButtonModifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (isWriteable) {
|
if (accountViewModel.isWriteable()) {
|
||||||
if (hasBoosted) {
|
if (accountViewModel.hasBoosted(baseNote)) {
|
||||||
accountViewModel.deleteBoostsTo(baseNote)
|
accountViewModel.deleteBoostsTo(baseNote)
|
||||||
} else {
|
} else {
|
||||||
wantsToBoost = true
|
wantsToBoost = true
|
||||||
@@ -256,16 +230,45 @@ fun BoostReaction(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Icon(
|
BoostIcon(baseNote, iconSize, grayTint, accountViewModel.userProfile())
|
||||||
painter = painterResource(R.drawable.ic_retweeted),
|
}
|
||||||
null,
|
|
||||||
modifier = iconModifier,
|
BoostText(baseNote, grayTint)
|
||||||
tint = if (wasBoostedByLoggedIn) Color.Unspecified else grayTint
|
}
|
||||||
)
|
|
||||||
|
@Composable
|
||||||
|
fun BoostIcon(baseNote: Note, iconSize: Dp = 20.dp, grayTint: Color, loggedIn: User) {
|
||||||
|
val boostsState by baseNote.live().boosts.observeAsState()
|
||||||
|
|
||||||
|
val iconTint by remember(boostsState) {
|
||||||
|
derivedStateOf {
|
||||||
|
if (boostsState?.note?.isBoostedBy(loggedIn) == true) Color.Unspecified else grayTint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconModifier = remember {
|
||||||
|
Modifier.size(iconSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_retweeted),
|
||||||
|
null,
|
||||||
|
modifier = iconModifier,
|
||||||
|
tint = iconTint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BoostText(baseNote: Note, grayTint: Color) {
|
||||||
|
val boostsState by baseNote.live().boosts.observeAsState()
|
||||||
|
val boostCount by remember(boostsState) {
|
||||||
|
derivedStateOf {
|
||||||
|
" " + showCount(boostsState?.note?.boosts?.size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
" $boostCount",
|
boostCount,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = grayTint
|
color = grayTint
|
||||||
)
|
)
|
||||||
@@ -279,29 +282,6 @@ fun LikeReaction(
|
|||||||
iconSize: Dp = 20.dp,
|
iconSize: Dp = 20.dp,
|
||||||
heartSize: Dp = 16.dp
|
heartSize: Dp = 16.dp
|
||||||
) {
|
) {
|
||||||
val reactionsState by baseNote.live().reactions.observeAsState()
|
|
||||||
val reactedNote = remember(reactionsState) { reactionsState?.note } ?: return
|
|
||||||
|
|
||||||
val hasReacted by remember(reactionsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
accountViewModel.hasReactedTo(baseNote)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val wasReactedByLoggedIn by remember(reactionsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
reactedNote.isReactedBy(accountViewModel.userProfile())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isWriteable = remember { accountViewModel.isWriteable() }
|
|
||||||
|
|
||||||
val reactionCount by remember(reactionsState) {
|
|
||||||
derivedStateOf {
|
|
||||||
showCount(reactedNote.reactions.size)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
@@ -309,15 +289,11 @@ fun LikeReaction(
|
|||||||
Modifier.size(iconSize)
|
Modifier.size(iconSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
val iconModifier = remember {
|
|
||||||
Modifier.size(heartSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton(
|
IconButton(
|
||||||
modifier = iconButtonModifier,
|
modifier = iconButtonModifier,
|
||||||
onClick = {
|
onClick = {
|
||||||
if (isWriteable) {
|
if (accountViewModel.isWriteable()) {
|
||||||
if (hasReacted) {
|
if (accountViewModel.hasReactedTo(baseNote)) {
|
||||||
accountViewModel.deleteReactionTo(baseNote)
|
accountViewModel.deleteReactionTo(baseNote)
|
||||||
} else {
|
} else {
|
||||||
accountViewModel.reactTo(baseNote)
|
accountViewModel.reactTo(baseNote)
|
||||||
@@ -333,25 +309,55 @@ fun LikeReaction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
if (wasReactedByLoggedIn) {
|
LikeIcon(baseNote, heartSize, grayTint, accountViewModel.userProfile())
|
||||||
Icon(
|
}
|
||||||
painter = painterResource(R.drawable.ic_liked),
|
|
||||||
null,
|
LikeText(baseNote, grayTint)
|
||||||
modifier = iconModifier,
|
}
|
||||||
tint = Color.Unspecified
|
|
||||||
)
|
@Composable
|
||||||
} else {
|
fun LikeIcon(baseNote: Note, iconSize: Dp = 20.dp, grayTint: Color, loggedIn: User) {
|
||||||
Icon(
|
val reactionsState by baseNote.live().reactions.observeAsState()
|
||||||
painter = painterResource(R.drawable.ic_like),
|
|
||||||
null,
|
val wasReactedByLoggedIn by remember(reactionsState) {
|
||||||
modifier = iconModifier,
|
derivedStateOf {
|
||||||
tint = grayTint
|
reactionsState?.note?.isReactedBy(loggedIn) == true
|
||||||
)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val iconModifier = remember {
|
||||||
|
Modifier.size(iconSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasReactedByLoggedIn) {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_liked),
|
||||||
|
null,
|
||||||
|
modifier = iconModifier,
|
||||||
|
tint = Color.Unspecified
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
painter = painterResource(R.drawable.ic_like),
|
||||||
|
null,
|
||||||
|
modifier = iconModifier,
|
||||||
|
tint = grayTint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun LikeText(baseNote: Note, grayTint: Color) {
|
||||||
|
val reactionsState by baseNote.live().reactions.observeAsState()
|
||||||
|
|
||||||
|
val reactionsCount by remember(reactionsState) {
|
||||||
|
derivedStateOf {
|
||||||
|
" " + showCount(reactionsState?.note?.reactions?.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
" $reactionCount",
|
reactionsCount,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = grayTint
|
color = grayTint
|
||||||
)
|
)
|
||||||
@@ -363,16 +369,12 @@ fun ZapReaction(
|
|||||||
baseNote: Note,
|
baseNote: Note,
|
||||||
grayTint: Color,
|
grayTint: Color,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
textModifier: Modifier = Modifier,
|
|
||||||
iconSize: Dp = 20.dp,
|
iconSize: Dp = 20.dp,
|
||||||
animationSize: Dp = 14.dp
|
animationSize: Dp = 14.dp
|
||||||
) {
|
) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
val accountState by accountViewModel.accountLiveData.observeAsState()
|
||||||
val account = remember(accountState) { accountState?.account } ?: return
|
val account = remember(accountState) { accountState?.account } ?: return
|
||||||
|
|
||||||
val zapsState by baseNote.live().zaps.observeAsState()
|
|
||||||
val zappedNote = remember(zapsState) { zapsState?.note } ?: return
|
|
||||||
|
|
||||||
var wantsToZap by remember { mutableStateOf(false) }
|
var wantsToZap by remember { mutableStateOf(false) }
|
||||||
var wantsToChangeZapAmount by remember { mutableStateOf(false) }
|
var wantsToChangeZapAmount by remember { mutableStateOf(false) }
|
||||||
var wantsToSetCustomZap by remember { mutableStateOf(false) }
|
var wantsToSetCustomZap by remember { mutableStateOf(false) }
|
||||||
@@ -382,32 +384,6 @@ fun ZapReaction(
|
|||||||
|
|
||||||
var zappingProgress by remember { mutableStateOf(0f) }
|
var zappingProgress by remember { mutableStateOf(0f) }
|
||||||
|
|
||||||
var wasZappedByLoggedInUser by remember { mutableStateOf(false) }
|
|
||||||
var zapAmountTxt by remember { mutableStateOf<String>("") }
|
|
||||||
|
|
||||||
LaunchedEffect(key1 = zapsState) {
|
|
||||||
scope.launch(Dispatchers.IO) {
|
|
||||||
if (!wasZappedByLoggedInUser) {
|
|
||||||
val newWasZapped = accountViewModel.calculateIfNoteWasZappedByAccount(zappedNote)
|
|
||||||
|
|
||||||
if (wasZappedByLoggedInUser != newWasZapped) {
|
|
||||||
wasZappedByLoggedInUser = newWasZapped
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val newZapAmount = showAmount(account.calculateZappedAmount(zappedNote))
|
|
||||||
if (newZapAmount != zapAmountTxt) {
|
|
||||||
zapAmountTxt = newZapAmount
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wasZappedByLoggedInUser) {
|
|
||||||
if (abs(zappingProgress - 1) < 0.001) {
|
|
||||||
zappingProgress = 1f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = CenterVertically,
|
verticalAlignment = CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@@ -498,6 +474,7 @@ fun ZapReaction(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToChangeZapAmount) {
|
if (wantsToChangeZapAmount) {
|
||||||
UpdateZapAmountDialog({ wantsToChangeZapAmount = false }, account = account)
|
UpdateZapAmountDialog({ wantsToChangeZapAmount = false }, account = account)
|
||||||
}
|
}
|
||||||
@@ -506,28 +483,93 @@ fun ZapReaction(
|
|||||||
ZapCustomDialog({ wantsToSetCustomZap = false }, account = account, accountViewModel, baseNote)
|
ZapCustomDialog({ wantsToSetCustomZap = false }, account = account, accountViewModel, baseNote)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasZappedByLoggedInUser) {
|
if (zappingProgress > 0.00001 && zappingProgress < 0.99999) {
|
||||||
Icon(
|
Spacer(Modifier.width(3.dp))
|
||||||
imageVector = Icons.Default.Bolt,
|
|
||||||
contentDescription = stringResource(R.string.zaps),
|
val animatedProgress = animateFloatAsState(
|
||||||
modifier = Modifier.size(iconSize),
|
targetValue = zappingProgress,
|
||||||
tint = BitcoinOrange
|
animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
|
||||||
|
).value
|
||||||
|
|
||||||
|
CircularProgressIndicator(
|
||||||
|
progress = animatedProgress,
|
||||||
|
modifier = Modifier.size(animationSize),
|
||||||
|
strokeWidth = 2.dp
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if (zappingProgress < 0.1 || zappingProgress > 0.99) {
|
ZapIcon(
|
||||||
Icon(
|
baseNote,
|
||||||
imageVector = Icons.Outlined.Bolt,
|
iconSize,
|
||||||
contentDescription = stringResource(id = R.string.zaps),
|
grayTint,
|
||||||
modifier = Modifier.size(iconSize),
|
accountViewModel
|
||||||
tint = grayTint
|
)
|
||||||
)
|
}
|
||||||
} else {
|
}
|
||||||
Spacer(Modifier.width(3.dp))
|
|
||||||
CircularProgressIndicator(
|
ZapAmountText(baseNote, grayTint, accountViewModel)
|
||||||
progress = zappingProgress,
|
}
|
||||||
modifier = Modifier.size(animationSize),
|
|
||||||
strokeWidth = 2.dp
|
@Composable
|
||||||
)
|
private fun ZapIcon(
|
||||||
|
baseNote: Note,
|
||||||
|
iconSize: Dp,
|
||||||
|
grayTint: Color,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
var wasZappedByLoggedInUser by remember { mutableStateOf(false) }
|
||||||
|
val zapsState by baseNote.live().zaps.observeAsState()
|
||||||
|
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
LaunchedEffect(key1 = zapsState) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
zapsState?.note?.let {
|
||||||
|
if (!wasZappedByLoggedInUser) {
|
||||||
|
val newWasZapped = accountViewModel.calculateIfNoteWasZappedByAccount(it)
|
||||||
|
|
||||||
|
if (wasZappedByLoggedInUser != newWasZapped) {
|
||||||
|
wasZappedByLoggedInUser = newWasZapped
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasZappedByLoggedInUser) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Bolt,
|
||||||
|
contentDescription = stringResource(R.string.zaps),
|
||||||
|
modifier = remember { Modifier.size(iconSize) },
|
||||||
|
tint = BitcoinOrange
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Bolt,
|
||||||
|
contentDescription = stringResource(id = R.string.zaps),
|
||||||
|
modifier = remember { Modifier.size(iconSize) },
|
||||||
|
tint = grayTint
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ZapAmountText(
|
||||||
|
baseNote: Note,
|
||||||
|
grayTint: Color,
|
||||||
|
accountViewModel: AccountViewModel
|
||||||
|
) {
|
||||||
|
val zapsState by baseNote.live().zaps.observeAsState()
|
||||||
|
val zappedNote = remember(zapsState) { zapsState?.note } ?: return
|
||||||
|
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
var zapAmountTxt by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
LaunchedEffect(key1 = zapsState) {
|
||||||
|
scope.launch(Dispatchers.IO) {
|
||||||
|
val newZapAmount = showAmount(accountViewModel.calculateZapAmount(zappedNote))
|
||||||
|
if (newZapAmount != zapAmountTxt) {
|
||||||
|
zapAmountTxt = newZapAmount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -535,8 +577,7 @@ fun ZapReaction(
|
|||||||
Text(
|
Text(
|
||||||
zapAmountTxt,
|
zapAmountTxt,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
color = grayTint,
|
color = grayTint
|
||||||
modifier = textModifier
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.vitorpamplona.amethyst.service.model.ReportEvent
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import java.math.BigDecimal
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -66,6 +67,10 @@ class AccountViewModel(private val account: Account) : ViewModel() {
|
|||||||
return account.calculateIfNoteWasZappedByAccount(zappedNote)
|
return account.calculateIfNoteWasZappedByAccount(zappedNote)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun calculateZapAmount(zappedNote: Note): BigDecimal {
|
||||||
|
return account.calculateZappedAmount(zappedNote)
|
||||||
|
}
|
||||||
|
|
||||||
fun zap(note: Note, amount: Long, pollOption: Int?, message: String, context: Context, onError: (String) -> Unit, onProgress: (percent: Float) -> Unit, zapType: LnZapEvent.ZapType) {
|
fun zap(note: Note, amount: Long, pollOption: Int?, message: String, context: Context, onError: (String) -> Unit, onProgress: (percent: Float) -> Unit, zapType: LnZapEvent.ZapType) {
|
||||||
val lud16 = note.event?.zapAddress() ?: note.author?.info?.lud16?.trim() ?: note.author?.info?.lud06?.trim()
|
val lud16 = note.event?.zapAddress() ?: note.author?.info?.lud16?.trim() ?: note.author?.info?.lud06?.trim()
|
||||||
|
|
||||||
@@ -105,7 +110,7 @@ class AccountViewModel(private val account: Account) : ViewModel() {
|
|||||||
?: "Error parsing error message"
|
?: "Error parsing error message"
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
onProgress(0.99f)
|
onProgress(1f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ fun FloatingButtons(navController: NavHostController, accountViewModel: AccountV
|
|||||||
}
|
}
|
||||||
is AccountState.LoggedIn -> {
|
is AccountState.LoggedIn -> {
|
||||||
if (currentRoute(navController)?.substringBefore("?") == Route.Home.base) {
|
if (currentRoute(navController)?.substringBefore("?") == Route.Home.base) {
|
||||||
NewNoteButton(state.account, accountViewModel, nav)
|
NewNoteButton(accountViewModel, nav)
|
||||||
}
|
}
|
||||||
if (currentRoute(navController) == Route.Message.base) {
|
if (currentRoute(navController) == Route.Message.base) {
|
||||||
ChannelFabColumn(state.account, nav)
|
ChannelFabColumn(state.account, nav)
|
||||||
|
|||||||
@@ -325,9 +325,6 @@ private fun RelayBadges(baseNote: Note) {
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ReactionsColumn(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
fun ReactionsColumn(baseNote: Note, accountViewModel: AccountViewModel, nav: (String) -> Unit) {
|
||||||
val accountState by accountViewModel.accountLiveData.observeAsState()
|
|
||||||
val account = accountState?.account ?: return
|
|
||||||
|
|
||||||
var wantsToReplyTo by remember {
|
var wantsToReplyTo by remember {
|
||||||
mutableStateOf<Note?>(null)
|
mutableStateOf<Note?>(null)
|
||||||
}
|
}
|
||||||
@@ -337,11 +334,11 @@ fun ReactionsColumn(baseNote: Note, accountViewModel: AccountViewModel, nav: (St
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToReplyTo != null) {
|
if (wantsToReplyTo != null) {
|
||||||
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, null, account, accountViewModel, nav)
|
NewPostView({ wantsToReplyTo = null }, wantsToReplyTo, null, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wantsToQuote != null) {
|
if (wantsToQuote != null) {
|
||||||
NewPostView({ wantsToQuote = null }, null, wantsToQuote, account, accountViewModel, nav)
|
NewPostView({ wantsToQuote = null }, null, wantsToQuote, accountViewModel, nav)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|||||||
Reference in New Issue
Block a user