Fixes the report card when the author has been blocked by the logged in user but the list loaded before the block user list.

This commit is contained in:
Vitor Pamplona
2023-08-31 14:53:43 -04:00
parent 669b33a3e1
commit 2771d34951
7 changed files with 96 additions and 107 deletions

View File

@@ -62,57 +62,63 @@ fun BlankNote(modifier: Modifier = Modifier, showDivider: Boolean = false, idHex
@Composable
fun HiddenNote(
reports: ImmutableSet<Note>,
isHiddenAuthor: Boolean,
accountViewModel: AccountViewModel,
modifier: Modifier = Modifier,
isQuote: Boolean = false,
nav: (String) -> Unit,
onClick: () -> Unit
) {
Column(modifier = modifier) {
Row(modifier = Modifier.padding(horizontal = if (!isQuote) 12.dp else 6.dp)) {
Column(modifier = Modifier.padding(start = if (!isQuote) 10.dp else 5.dp)) {
Row(
modifier = Modifier.padding(
start = 20.dp,
end = 20.dp
),
verticalAlignment = Alignment.CenterVertically
) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(30.dp)) {
Text(
text = stringResource(R.string.post_was_flagged_as_inappropriate_by),
color = Color.Gray
Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
Row(
modifier = Modifier.padding(start = if (!isQuote) 30.dp else 25.dp, end = 20.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(30.dp)
) {
Text(
text = stringResource(R.string.post_was_flagged_as_inappropriate_by),
color = Color.Gray
)
FlowRow(modifier = Modifier.padding(top = 10.dp)) {
if (isHiddenAuthor) {
UserPicture(
user = accountViewModel.userProfile(),
size = Size35dp,
nav = nav,
accountViewModel = accountViewModel
)
}
reports.forEach {
NoteAuthorPicture(
baseNote = it,
size = Size35dp,
nav = nav,
accountViewModel = accountViewModel
)
FlowRow(modifier = Modifier.padding(top = 10.dp)) {
reports.forEach {
NoteAuthorPicture(
baseNote = it,
nav = nav,
accountViewModel = accountViewModel,
size = Size35dp
)
}
}
Button(
modifier = Modifier.padding(top = 10.dp),
onClick = onClick,
shape = ButtonBorder,
colors = ButtonDefaults
.buttonColors(
backgroundColor = MaterialTheme.colors.primary
),
contentPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp)
) {
Text(text = stringResource(R.string.show_anyway), color = Color.White)
}
}
}
Divider(
thickness = 0.25.dp
)
Button(
modifier = Modifier.padding(top = 10.dp),
onClick = onClick,
shape = ButtonBorder,
colors = ButtonDefaults
.buttonColors(
backgroundColor = MaterialTheme.colors.primary
),
contentPadding = PaddingValues(vertical = 6.dp, horizontal = 16.dp)
) {
Text(text = stringResource(R.string.show_anyway), color = Color.White)
}
}
}
Divider(
thickness = 0.25.dp
)
}
}

View File

@@ -76,7 +76,6 @@ import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_LIVE
import com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_PLANNED
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -135,13 +134,9 @@ fun CheckHiddenChannelCardCompose(
nav: (String) -> Unit
) {
if (showHidden) {
var state by remember {
val state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
@@ -185,19 +180,14 @@ fun LoadedChannelCardCompose(
) {
var state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
val scope = rememberCoroutineScope()
WatchForReports(note, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) {
val newState = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports)
WatchForReports(note, accountViewModel) { newState ->
if (state != newState) {
scope.launch(Dispatchers.Main) {
state = newState
}
@@ -219,7 +209,7 @@ fun LoadedChannelCardCompose(
@Composable
fun RenderChannelCardReportState(
state: NoteComposeReportState,
state: AccountViewModel.NoteComposeReportState,
note: Note,
routeForLastRead: String? = null,
modifier: Modifier = Modifier,
@@ -233,6 +223,7 @@ fun RenderChannelCardReportState(
if (showHiddenNote) {
HiddenNote(
state.relevantReports,
state.isHiddenAuthor,
accountViewModel,
modifier,
false,

View File

@@ -69,8 +69,6 @@ import com.vitorpamplona.quartz.events.ChatMessageEvent
import com.vitorpamplona.quartz.events.ImmutableListOfLists
import com.vitorpamplona.quartz.events.PrivateDmEvent
import com.vitorpamplona.quartz.events.toImmutableListOfLists
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableSet
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -152,17 +150,13 @@ fun LoadedChatMessageCompose(
) {
var state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
WatchForReports(baseNote, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) {
state = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports.toImmutableSet())
WatchForReports(baseNote, accountViewModel) { newState ->
if (state != newState) {
state = newState
}
}
@@ -178,6 +172,7 @@ fun LoadedChatMessageCompose(
if (it) {
HiddenNote(
state.relevantReports,
state.isHiddenAuthor,
accountViewModel,
Modifier,
innerQuote,

View File

@@ -38,7 +38,6 @@ import androidx.compose.material.Text
import androidx.compose.material.darkColors
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
@@ -196,7 +195,6 @@ import com.vitorpamplona.quartz.events.TextNoteEvent
import com.vitorpamplona.quartz.events.UserMetadata
import com.vitorpamplona.quartz.events.toImmutableListOfLists
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.ImmutableSet
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList
@@ -277,11 +275,7 @@ fun CheckHiddenNoteCompose(
// Ignores reports as well
val state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
@@ -324,13 +318,6 @@ fun CheckHiddenNoteCompose(
}
}
@Immutable
data class NoteComposeReportState(
val isAcceptable: Boolean,
val canPreview: Boolean,
val relevantReports: ImmutableSet<Note>
)
@Composable
fun LoadedNoteCompose(
note: Note,
@@ -347,19 +334,14 @@ fun LoadedNoteCompose(
) {
var state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
val scope = rememberCoroutineScope()
WatchForReports(note, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) {
val newState = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports)
WatchForReports(note, accountViewModel) { newState ->
if (state != newState) {
scope.launch(Dispatchers.Main) {
state = newState
}
@@ -386,7 +368,7 @@ fun LoadedNoteCompose(
@Composable
fun RenderReportState(
state: NoteComposeReportState,
state: AccountViewModel.NoteComposeReportState,
note: Note,
routeForLastRead: String? = null,
modifier: Modifier = Modifier,
@@ -405,6 +387,7 @@ fun RenderReportState(
if (showHiddenNote) {
HiddenNote(
state.relevantReports,
state.isHiddenAuthor,
accountViewModel,
modifier,
isBoostedNote,
@@ -436,7 +419,7 @@ fun RenderReportState(
fun WatchForReports(
note: Note,
accountViewModel: AccountViewModel,
onChange: (Boolean, Boolean, ImmutableSet<Note>) -> Unit
onChange: (AccountViewModel.NoteComposeReportState) -> Unit
) {
val userFollowsState by accountViewModel.userFollows.observeAsState()
val noteReportsState by note.live().reports.observeAsState()

View File

@@ -262,6 +262,7 @@ fun NoteMaster(
HiddenNote(
reports,
note.author?.let { account.isHidden(it) } ?: false,
accountViewModel,
Modifier,
false,

View File

@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.content.Context
import android.content.Intent
import android.net.Uri
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.core.content.ContextCompat
import androidx.lifecycle.LiveData
@@ -410,14 +411,24 @@ class AccountViewModel(val account: Account) : ViewModel() {
return account.defaultZapType
}
fun isNoteAcceptable(note: Note, onReady: (Boolean, Boolean, ImmutableSet<Note>) -> Unit) {
@Immutable
data class NoteComposeReportState(
val isAcceptable: Boolean = true,
val canPreview: Boolean = true,
val isHiddenAuthor: Boolean = false,
val relevantReports: ImmutableSet<Note> = persistentSetOf()
)
fun isNoteAcceptable(note: Note, onReady: (NoteComposeReportState) -> Unit) {
viewModelScope.launch {
val isFromLoggedIn = note.author?.pubkeyHex == userProfile().pubkeyHex
val isFromLoggedInFollow = note.author?.let { userProfile().isFollowingCached(it) } ?: true
if (isFromLoggedIn || isFromLoggedInFollow) {
// No need to process if from trusted people
onReady(true, true, persistentSetOf())
onReady(NoteComposeReportState(true, true, false, persistentSetOf()))
} else if (note.author?.let { account.isHidden(it) } == true) {
onReady(NoteComposeReportState(false, false, true, persistentSetOf()))
} else {
val newCanPreview = !note.hasAnyReports()
@@ -425,11 +436,18 @@ class AccountViewModel(val account: Account) : ViewModel() {
if (newCanPreview && newIsAcceptable) {
// No need to process reports if nothing is wrong
onReady(true, true, persistentSetOf())
onReady(NoteComposeReportState(true, true, false, persistentSetOf()))
} else {
val newRelevantReports = account.getRelevantReports(note)
onReady(newIsAcceptable, newCanPreview, newRelevantReports.toImmutableSet())
onReady(
NoteComposeReportState(
newIsAcceptable,
newCanPreview,
false,
newRelevantReports.toImmutableSet()
)
)
}
}
}

View File

@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
@@ -52,7 +53,6 @@ import com.vitorpamplona.amethyst.ui.note.FileStorageHeaderDisplay
import com.vitorpamplona.amethyst.ui.note.HiddenNote
import com.vitorpamplona.amethyst.ui.note.LikeReaction
import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture
import com.vitorpamplona.amethyst.ui.note.NoteComposeReportState
import com.vitorpamplona.amethyst.ui.note.NoteDropDownMenu
import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.RenderRelay
@@ -76,7 +76,6 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText
import com.vitorpamplona.quartz.events.FileHeaderEvent
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -250,19 +249,14 @@ fun LoadedVideoCompose(
) {
var state by remember {
mutableStateOf(
NoteComposeReportState(
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
AccountViewModel.NoteComposeReportState()
)
}
val scope = rememberCoroutineScope()
WatchForReports(note, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) {
val newState = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports)
WatchForReports(note, accountViewModel) { newState ->
if (state != newState) {
scope.launch(Dispatchers.Main) {
state = newState
}
@@ -281,7 +275,7 @@ fun LoadedVideoCompose(
@Composable
fun RenderReportState(
state: NoteComposeReportState,
state: AccountViewModel.NoteComposeReportState,
note: Note,
accountViewModel: AccountViewModel,
nav: (String) -> Unit
@@ -290,11 +284,12 @@ fun RenderReportState(
Crossfade(targetState = !state.isAcceptable && !showReportedNote) { showHiddenNote ->
if (showHiddenNote) {
Column(remember { Modifier.fillMaxSize(1f) }, verticalArrangement = Arrangement.Center) {
Column(remember { Modifier.fillMaxSize() }, verticalArrangement = Arrangement.Center) {
HiddenNote(
state.relevantReports,
state.isHiddenAuthor,
accountViewModel,
Modifier,
Modifier.fillMaxWidth(),
false,
nav,
onClick = { showReportedNote = true }