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,34 +62,42 @@ fun BlankNote(modifier: Modifier = Modifier, showDivider: Boolean = false, idHex
@Composable @Composable
fun HiddenNote( fun HiddenNote(
reports: ImmutableSet<Note>, reports: ImmutableSet<Note>,
isHiddenAuthor: Boolean,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
isQuote: Boolean = false, isQuote: Boolean = false,
nav: (String) -> Unit, nav: (String) -> Unit,
onClick: () -> Unit onClick: () -> Unit
) { ) {
Column(modifier = modifier) { Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
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( Row(
modifier = Modifier.padding( modifier = Modifier.padding(start = if (!isQuote) 30.dp else 25.dp, end = 20.dp),
start = 20.dp, horizontalArrangement = Arrangement.Center,
end = 20.dp
),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.padding(30.dp)) { Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(30.dp)
) {
Text( Text(
text = stringResource(R.string.post_was_flagged_as_inappropriate_by), text = stringResource(R.string.post_was_flagged_as_inappropriate_by),
color = Color.Gray color = Color.Gray
) )
FlowRow(modifier = Modifier.padding(top = 10.dp)) { FlowRow(modifier = Modifier.padding(top = 10.dp)) {
if (isHiddenAuthor) {
UserPicture(
user = accountViewModel.userProfile(),
size = Size35dp,
nav = nav,
accountViewModel = accountViewModel
)
}
reports.forEach { reports.forEach {
NoteAuthorPicture( NoteAuthorPicture(
baseNote = it, baseNote = it,
size = Size35dp,
nav = nav, nav = nav,
accountViewModel = accountViewModel, accountViewModel = accountViewModel
size = Size35dp
) )
} }
} }
@@ -113,6 +121,4 @@ fun HiddenNote(
thickness = 0.25.dp 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 com.vitorpamplona.quartz.events.LiveActivitiesEvent.Companion.STATUS_PLANNED
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -135,13 +134,9 @@ fun CheckHiddenChannelCardCompose(
nav: (String) -> Unit nav: (String) -> Unit
) { ) {
if (showHidden) { if (showHidden) {
var state by remember { val state by remember {
mutableStateOf( mutableStateOf(
NoteComposeReportState( AccountViewModel.NoteComposeReportState()
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
) )
} }
@@ -185,19 +180,14 @@ fun LoadedChannelCardCompose(
) { ) {
var state by remember { var state by remember {
mutableStateOf( mutableStateOf(
NoteComposeReportState( AccountViewModel.NoteComposeReportState()
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
) )
} }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
WatchForReports(note, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports -> WatchForReports(note, accountViewModel) { newState ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) { if (state != newState) {
val newState = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports)
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
state = newState state = newState
} }
@@ -219,7 +209,7 @@ fun LoadedChannelCardCompose(
@Composable @Composable
fun RenderChannelCardReportState( fun RenderChannelCardReportState(
state: NoteComposeReportState, state: AccountViewModel.NoteComposeReportState,
note: Note, note: Note,
routeForLastRead: String? = null, routeForLastRead: String? = null,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
@@ -233,6 +223,7 @@ fun RenderChannelCardReportState(
if (showHiddenNote) { if (showHiddenNote) {
HiddenNote( HiddenNote(
state.relevantReports, state.relevantReports,
state.isHiddenAuthor,
accountViewModel, accountViewModel,
modifier, modifier,
false, false,

View File

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

View File

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

View File

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

View File

@@ -3,6 +3,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
@@ -410,14 +411,24 @@ class AccountViewModel(val account: Account) : ViewModel() {
return account.defaultZapType 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 { viewModelScope.launch {
val isFromLoggedIn = note.author?.pubkeyHex == userProfile().pubkeyHex val isFromLoggedIn = note.author?.pubkeyHex == userProfile().pubkeyHex
val isFromLoggedInFollow = note.author?.let { userProfile().isFollowingCached(it) } ?: true val isFromLoggedInFollow = note.author?.let { userProfile().isFollowingCached(it) } ?: true
if (isFromLoggedIn || isFromLoggedInFollow) { if (isFromLoggedIn || isFromLoggedInFollow) {
// No need to process if from trusted people // 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 { } else {
val newCanPreview = !note.hasAnyReports() val newCanPreview = !note.hasAnyReports()
@@ -425,11 +436,18 @@ class AccountViewModel(val account: Account) : ViewModel() {
if (newCanPreview && newIsAcceptable) { if (newCanPreview && newIsAcceptable) {
// No need to process reports if nothing is wrong // No need to process reports if nothing is wrong
onReady(true, true, persistentSetOf()) onReady(NoteComposeReportState(true, true, false, persistentSetOf()))
} else { } else {
val newRelevantReports = account.getRelevantReports(note) 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.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size 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.HiddenNote
import com.vitorpamplona.amethyst.ui.note.LikeReaction import com.vitorpamplona.amethyst.ui.note.LikeReaction
import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture 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.NoteDropDownMenu
import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay
import com.vitorpamplona.amethyst.ui.note.RenderRelay 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.FileHeaderEvent
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentSetOf
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -250,19 +249,14 @@ fun LoadedVideoCompose(
) { ) {
var state by remember { var state by remember {
mutableStateOf( mutableStateOf(
NoteComposeReportState( AccountViewModel.NoteComposeReportState()
isAcceptable = true,
canPreview = true,
relevantReports = persistentSetOf()
)
) )
} }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
WatchForReports(note, accountViewModel) { newIsAcceptable, newCanPreview, newRelevantReports -> WatchForReports(note, accountViewModel) { newState ->
if (newIsAcceptable != state.isAcceptable || newCanPreview != state.canPreview) { if (state != newState) {
val newState = NoteComposeReportState(newIsAcceptable, newCanPreview, newRelevantReports)
scope.launch(Dispatchers.Main) { scope.launch(Dispatchers.Main) {
state = newState state = newState
} }
@@ -281,7 +275,7 @@ fun LoadedVideoCompose(
@Composable @Composable
fun RenderReportState( fun RenderReportState(
state: NoteComposeReportState, state: AccountViewModel.NoteComposeReportState,
note: Note, note: Note,
accountViewModel: AccountViewModel, accountViewModel: AccountViewModel,
nav: (String) -> Unit nav: (String) -> Unit
@@ -290,11 +284,12 @@ fun RenderReportState(
Crossfade(targetState = !state.isAcceptable && !showReportedNote) { showHiddenNote -> Crossfade(targetState = !state.isAcceptable && !showReportedNote) { showHiddenNote ->
if (showHiddenNote) { if (showHiddenNote) {
Column(remember { Modifier.fillMaxSize(1f) }, verticalArrangement = Arrangement.Center) { Column(remember { Modifier.fillMaxSize() }, verticalArrangement = Arrangement.Center) {
HiddenNote( HiddenNote(
state.relevantReports, state.relevantReports,
state.isHiddenAuthor,
accountViewModel, accountViewModel,
Modifier, Modifier.fillMaxWidth(),
false, false,
nav, nav,
onClick = { showReportedNote = true } onClick = { showReportedNote = true }