feat: make report dialogues up to date, add user report
Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
parent
f611296670
commit
9da6b040a8
|
|
@ -12,8 +12,16 @@ import kotlinx.serialization.encoding.Encoder
|
|||
enum class ContentReportReason(val value: String) {
|
||||
NoneSpecified("NoneSpecified"),
|
||||
Illegal("Illegal"),
|
||||
IllegalGoods("IllegalGoods"),
|
||||
IllegalExtortion("IllegalExtortion"),
|
||||
IllegalPornography("IllegalPornography"),
|
||||
IllegalHacking("IllegalHacking"),
|
||||
ExtremeViolence("ExtremeViolence"),
|
||||
PromotesHarm("PromotesHarm"),
|
||||
UnsolicitedSpam("UnsolicitedSpam"),
|
||||
Raid("Raid"),
|
||||
SpamAbuse("SpamAbuse"),
|
||||
ScamsFraud("ScamsFraud"),
|
||||
Malware("Malware"),
|
||||
Harassment("Harassment");
|
||||
|
||||
|
|
@ -30,8 +38,16 @@ enum class ContentReportReason(val value: String) {
|
|||
when (val value = decoder.decodeString()) {
|
||||
"NoneSpecified" -> NoneSpecified
|
||||
"Illegal" -> Illegal
|
||||
"IllegalGoods" -> IllegalGoods
|
||||
"IllegalExtortion" -> IllegalExtortion
|
||||
"IllegalPornography" -> IllegalPornography
|
||||
"IllegalHacking" -> IllegalHacking
|
||||
"ExtremeViolence" -> ExtremeViolence
|
||||
"PromotesHarm" -> PromotesHarm
|
||||
"UnsolicitedSpam" -> UnsolicitedSpam
|
||||
"Raid" -> Raid
|
||||
"SpamAbuse" -> SpamAbuse
|
||||
"ScamsFraud" -> ScamsFraud
|
||||
"Malware" -> Malware
|
||||
"Harassment" -> Harassment
|
||||
else -> throw IllegalArgumentException("Unknown ContentReportReason: $value")
|
||||
|
|
@ -46,6 +62,7 @@ enum class ContentReportReason(val value: String) {
|
|||
@Serializable
|
||||
enum class UserReportReason(val value: String) {
|
||||
NoneSpecified("NoneSpecified"),
|
||||
UnsolicitedSpam("UnsolicitedSpam"),
|
||||
SpamAbuse("SpamAbuse"),
|
||||
InappropriateProfile("InappropriateProfile"),
|
||||
Impersonation("Impersonation"),
|
||||
|
|
@ -64,6 +81,7 @@ enum class UserReportReason(val value: String) {
|
|||
override fun deserialize(decoder: Decoder): UserReportReason =
|
||||
when (val value = decoder.decodeString()) {
|
||||
"NoneSpecified" -> NoneSpecified
|
||||
"UnsolicitedSpam" -> UnsolicitedSpam
|
||||
"SpamAbuse" -> SpamAbuse
|
||||
"InappropriateProfile" -> InappropriateProfile
|
||||
"Impersonation" -> Impersonation
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ fun SelfUserOverview() {
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun UserOverview(user: User) {
|
||||
fun UserOverview(user: User, internalPadding: Boolean = true) {
|
||||
var profile by remember { mutableStateOf<Profile?>(null) }
|
||||
|
||||
LaunchedEffect(user) {
|
||||
|
|
@ -67,7 +67,7 @@ fun UserOverview(user: User) {
|
|||
}
|
||||
}
|
||||
|
||||
RawUserOverview(user, profile)
|
||||
RawUserOverview(user, profile, internalPadding = internalPadding)
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -75,7 +75,8 @@ fun RawUserOverview(
|
|||
user: User,
|
||||
profile: Profile? = null,
|
||||
pfpUrl: String? = null,
|
||||
backgroundUrl: String? = null
|
||||
backgroundUrl: String? = null,
|
||||
internalPadding: Boolean = true
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
var teamMemberFlair by remember { mutableStateOf<Brush?>(null) }
|
||||
|
|
@ -94,7 +95,7 @@ fun RawUserOverview(
|
|||
Box(
|
||||
contentAlignment = Alignment.BottomStart,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(horizontal = if (internalPadding) 16.dp else 0.dp)
|
||||
.clip(MaterialTheme.shapes.large)
|
||||
.then(
|
||||
if (user.id in SpecialUsers.TEAM_MEMBER_FLAIRS.keys) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import androidx.compose.foundation.verticalScroll
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DismissibleDrawerSheet
|
||||
import androidx.compose.material3.DismissibleNavigationDrawer
|
||||
import androidx.compose.material3.DrawerState
|
||||
|
|
@ -95,6 +94,7 @@ import chat.revolt.internals.Changelogs
|
|||
import chat.revolt.ndk.Pipebomb
|
||||
import chat.revolt.persistence.KVStorage
|
||||
import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog
|
||||
import chat.revolt.screens.chat.dialogs.safety.ReportUserDialog
|
||||
import chat.revolt.screens.chat.views.FriendsScreen
|
||||
import chat.revolt.screens.chat.views.HomeScreen
|
||||
import chat.revolt.screens.chat.views.NoCurrentChannelScreen
|
||||
|
|
@ -1050,16 +1050,10 @@ fun ChannelNavigator(
|
|||
dialog("report/user/{userId}") { backStackEntry ->
|
||||
val userId = backStackEntry.arguments?.getString("userId")
|
||||
if (userId != null) {
|
||||
AlertDialog(onDismissRequest = {
|
||||
navController.popBackStack()
|
||||
}) {
|
||||
Text("Report user $userId")
|
||||
Button(onClick = {
|
||||
navController.popBackStack()
|
||||
}) {
|
||||
Text("Close")
|
||||
}
|
||||
}
|
||||
ReportUserDialog(
|
||||
navController = navController,
|
||||
userId = userId
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,9 @@ import androidx.compose.material3.AlertDialog
|
|||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconToggleButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -50,13 +53,14 @@ import chat.revolt.components.chat.Message
|
|||
import chat.revolt.components.generic.FormTextField
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
enum class ReportFlowState {
|
||||
enum class MessageReportFlowState {
|
||||
Reason,
|
||||
Sending,
|
||||
Done,
|
||||
Error
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ReportMessageDialog(navController: NavController, messageId: String) {
|
||||
val message = RevoltAPI.messageCache[messageId]
|
||||
|
|
@ -68,20 +72,28 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
val author = RevoltAPI.userCache[message.author]
|
||||
val messageIsBridged = author?.let { author.bot != null && message.masquerade != null } ?: false
|
||||
|
||||
val state = remember { mutableStateOf(ReportFlowState.Reason) }
|
||||
val state = remember { mutableStateOf(MessageReportFlowState.Reason) }
|
||||
|
||||
val selectedReason = remember { mutableStateOf("Illegal") }
|
||||
val userAddedContext = remember { mutableStateOf("") }
|
||||
|
||||
when (state.value) {
|
||||
ReportFlowState.Reason -> {
|
||||
MessageReportFlowState.Reason -> {
|
||||
val reasons = mapOf(
|
||||
"Illegal" to stringResource(id = R.string.report_reason_content_illegal),
|
||||
"IllegalGoods" to stringResource(id = R.string.report_reason_content_illegal_goods),
|
||||
"IllegalExtortion" to stringResource(id = R.string.report_reason_content_illegal_extortion),
|
||||
"IllegalPornography" to stringResource(id = R.string.report_reason_content_illegal_pornography),
|
||||
"IllegalHacking" to stringResource(id = R.string.report_reason_content_illegal_hacking),
|
||||
"ExtremeViolence" to stringResource(id = R.string.report_reason_content_extreme_violence),
|
||||
"PromotesHarm" to stringResource(id = R.string.report_reason_content_promotes_harm),
|
||||
"UnsolicitedSpam" to stringResource(id = R.string.report_reason_content_unsolicited_spam),
|
||||
"Raid" to stringResource(id = R.string.report_reason_content_raid),
|
||||
"SpamAbuse" to stringResource(id = R.string.report_reason_content_spam_abuse),
|
||||
"ScamsFraud" to stringResource(id = R.string.report_reason_content_scams_fraud),
|
||||
"Malware" to stringResource(id = R.string.report_reason_content_malware),
|
||||
"Harassment" to stringResource(id = R.string.report_reason_content_harassment),
|
||||
"Other" to stringResource(id = R.string.report_reason_content_other)
|
||||
"NoneSpecified" to stringResource(id = R.string.report_reason_content_other)
|
||||
)
|
||||
val reasonDropdownExpanded = remember { mutableStateOf(false) }
|
||||
|
||||
|
|
@ -91,7 +103,7 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report),
|
||||
text = stringResource(id = R.string.report_message_heading),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
|
|
@ -134,38 +146,30 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Box {
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = reasonDropdownExpanded.value,
|
||||
onExpandedChange = {
|
||||
reasonDropdownExpanded.value = it
|
||||
},
|
||||
) {
|
||||
TextField(
|
||||
value = reasons[selectedReason.value]
|
||||
?: stringResource(id = R.string.unknown),
|
||||
onValueChange = {
|
||||
selectedReason.value = it
|
||||
},
|
||||
readOnly = true,
|
||||
onValueChange = {},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_reason)
|
||||
)
|
||||
},
|
||||
readOnly = true,
|
||||
trailingIcon = {
|
||||
IconToggleButton(
|
||||
checked = reasonDropdownExpanded.value,
|
||||
onCheckedChange = {
|
||||
reasonDropdownExpanded.value = it
|
||||
}
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ArrowDropDown,
|
||||
contentDescription = stringResource(
|
||||
id = R.string.report_reason
|
||||
)
|
||||
)
|
||||
}
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = reasonDropdownExpanded.value)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
colors = ExposedDropdownMenuDefaults.textFieldColors(),
|
||||
modifier = Modifier.menuAnchor()
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
ExposedDropdownMenu(
|
||||
expanded = reasonDropdownExpanded.value,
|
||||
onDismissRequest = {
|
||||
reasonDropdownExpanded.value = false
|
||||
|
|
@ -216,7 +220,7 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
state.value = ReportFlowState.Sending
|
||||
state.value = MessageReportFlowState.Sending
|
||||
},
|
||||
modifier = Modifier.testTag("report_send")
|
||||
) {
|
||||
|
|
@ -226,7 +230,7 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
)
|
||||
}
|
||||
|
||||
ReportFlowState.Sending -> {
|
||||
MessageReportFlowState.Sending -> {
|
||||
AlertDialog(
|
||||
onDismissRequest = {},
|
||||
title = {
|
||||
|
|
@ -250,9 +254,9 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
ContentReportReason.valueOf(selectedReason.value),
|
||||
userAddedContext.value
|
||||
)
|
||||
state.value = ReportFlowState.Done
|
||||
state.value = MessageReportFlowState.Done
|
||||
} catch (e: Error) {
|
||||
state.value = ReportFlowState.Error
|
||||
state.value = MessageReportFlowState.Error
|
||||
Log.e("ReportMessageDialog", "Failed to report message", e)
|
||||
return@launch
|
||||
}
|
||||
|
|
@ -265,7 +269,7 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
)
|
||||
}
|
||||
|
||||
ReportFlowState.Done -> {
|
||||
MessageReportFlowState.Done -> {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
AlertDialog(
|
||||
|
|
@ -334,7 +338,7 @@ fun ReportMessageDialog(navController: NavController, messageId: String) {
|
|||
)
|
||||
}
|
||||
|
||||
ReportFlowState.Error -> {
|
||||
MessageReportFlowState.Error -> {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
navController.popBackStack()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,353 @@
|
|||
package chat.revolt.screens.chat.dialogs.safety
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExposedDropdownMenuDefaults
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconToggleButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.testTag
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.navigation.NavController
|
||||
import chat.revolt.R
|
||||
import chat.revolt.api.RevoltAPI
|
||||
import chat.revolt.api.routes.safety.putMessageReport
|
||||
import chat.revolt.api.routes.safety.putUserReport
|
||||
import chat.revolt.api.routes.user.blockUser
|
||||
import chat.revolt.api.schemas.ContentReportReason
|
||||
import chat.revolt.api.schemas.UserReportReason
|
||||
import chat.revolt.components.chat.Message
|
||||
import chat.revolt.components.generic.FormTextField
|
||||
import chat.revolt.components.screens.settings.UserOverview
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
enum class UserReportFlowState {
|
||||
Reason,
|
||||
Sending,
|
||||
Done,
|
||||
Error
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ReportUserDialog(navController: NavController, userId: String) {
|
||||
val user = RevoltAPI.userCache[userId]
|
||||
if (user == null) {
|
||||
navController.popBackStack()
|
||||
return
|
||||
}
|
||||
|
||||
val state = remember { mutableStateOf(UserReportFlowState.Reason) }
|
||||
|
||||
val selectedReason = remember { mutableStateOf("UnsolicitedSpam") }
|
||||
val userAddedContext = remember { mutableStateOf("") }
|
||||
|
||||
when (state.value) {
|
||||
UserReportFlowState.Reason -> {
|
||||
val reasons = mapOf(
|
||||
"UnsolicitedSpam" to stringResource(id = R.string.report_reason_user_unsolicited_spam),
|
||||
"SpamAbuse" to stringResource(id = R.string.report_reason_user_spam_abuse),
|
||||
"InappropriateProfile" to stringResource(id = R.string.report_reason_user_inappropriate_content),
|
||||
"Impersonation" to stringResource(id = R.string.report_reason_user_impersonation),
|
||||
"BanEvasion" to stringResource(id = R.string.report_reason_user_ban_evasion),
|
||||
"Underage" to stringResource(id = R.string.report_reason_user_underage),
|
||||
"NoneSpecified" to stringResource(id = R.string.report_reason_user_other)
|
||||
)
|
||||
val reasonDropdownExpanded = remember { mutableStateOf(false) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
// nothing - prevent mistaps from closing the dialog
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_user_heading),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(text = stringResource(id = R.string.report_user))
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_user_preview),
|
||||
fontSize = 12.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
UserOverview(user, internalPadding = false)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = reasonDropdownExpanded.value,
|
||||
onExpandedChange = {
|
||||
reasonDropdownExpanded.value = it
|
||||
},
|
||||
) {
|
||||
TextField(
|
||||
value = reasons[selectedReason.value]
|
||||
?: stringResource(id = R.string.unknown),
|
||||
readOnly = true,
|
||||
onValueChange = {},
|
||||
label = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_reason)
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
ExposedDropdownMenuDefaults.TrailingIcon(expanded = reasonDropdownExpanded.value)
|
||||
},
|
||||
colors = ExposedDropdownMenuDefaults.textFieldColors(),
|
||||
modifier = Modifier.menuAnchor()
|
||||
)
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = reasonDropdownExpanded.value,
|
||||
onDismissRequest = {
|
||||
reasonDropdownExpanded.value = false
|
||||
}
|
||||
) {
|
||||
reasons.forEach { (key, value) ->
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = value)
|
||||
},
|
||||
onClick = {
|
||||
selectedReason.value = key
|
||||
reasonDropdownExpanded.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
FormTextField(
|
||||
value = userAddedContext.value,
|
||||
label = stringResource(id = R.string.report_reason_additional),
|
||||
onChange = {
|
||||
userAddedContext.value = it
|
||||
},
|
||||
supportingText = {
|
||||
Text(
|
||||
text = stringResource(
|
||||
id = R.string.report_reason_additional_hint
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
modifier = Modifier.testTag("report_cancel")
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.report_cancel))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
state.value = UserReportFlowState.Sending
|
||||
},
|
||||
modifier = Modifier.testTag("report_send")
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.report_submit))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
UserReportFlowState.Sending -> {
|
||||
AlertDialog(
|
||||
onDismissRequest = {},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_submitting),
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
LaunchedEffect(true) {
|
||||
launch {
|
||||
try {
|
||||
Log.d("ReportMessageDialog", "Reporting user $userId")
|
||||
putUserReport(
|
||||
userId,
|
||||
UserReportReason.valueOf(selectedReason.value),
|
||||
userAddedContext.value
|
||||
)
|
||||
state.value = UserReportFlowState.Done
|
||||
} catch (e: Error) {
|
||||
state.value = UserReportFlowState.Error
|
||||
Log.e("ReportMessageDialog", "Failed to report user", e)
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
dismissButton = {},
|
||||
confirmButton = {}
|
||||
)
|
||||
}
|
||||
|
||||
UserReportFlowState.Done -> {
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Check,
|
||||
contentDescription = null, // decorative
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_submit_success),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_submit_thanks),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_block_question),
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 16.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
modifier = Modifier.testTag("report_block_no")
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.report_block_no))
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
blockUser(userId)
|
||||
}
|
||||
navController.popBackStack()
|
||||
},
|
||||
modifier = Modifier.testTag("report_block_yes")
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.report_block_yes))
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
UserReportFlowState.Error -> {
|
||||
AlertDialog(
|
||||
onDismissRequest = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
icon = {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Close,
|
||||
contentDescription = null, // decorative
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_submit_error_header),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(id = R.string.report_submit_error),
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
modifier = Modifier.testTag("report_error_ok")
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.ok))
|
||||
}
|
||||
},
|
||||
confirmButton = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -303,23 +303,35 @@
|
|||
<string name="report">Report</string>
|
||||
<string name="report_cancel">Cancel</string>
|
||||
|
||||
<string name="report_message">Thank you for taking the time to report this message. Please provide a reason for reporting this message.</string>
|
||||
<string name="report_message_heading">Tell us what\'s wrong with this message</string>
|
||||
<string name="report_message">Thank you for taking the time to report this message. Your report will not be shared with the user who sent the message or the server\'s moderators.</string>
|
||||
<string name="report_message_preview">Selected message:</string>
|
||||
<string name="report_message_bridge_notice">Note: This message may have been sent from another platform. It is recommended to also report the message on the platform it was sent from.</string>
|
||||
<string name="report_server">Thank you for taking the time to report this server. Please provide a reason for reporting this server.</string>
|
||||
<string name="report_server_heading">Tell us what\'s wrong with this server</string>
|
||||
<string name="report_server">Thank you for taking the time to report this server. Your report will not be shared with the server\'s moderators.</string>
|
||||
<string name="report_server_preview">Selected server:</string>
|
||||
<string name="report_user">Thank you for taking the time to report this user. Please provide a reason for reporting this user.</string>
|
||||
<string name="report_user_heading">Tell us what\'s wrong with this user</string>
|
||||
<string name="report_user">Thank you for taking the time to report this user. Your report will not be shared with the user or the server\'s moderators.</string>
|
||||
<string name="report_user_preview">Selected user:</string>
|
||||
|
||||
<string name="report_reason">Reason</string>
|
||||
<string name="report_reason">Pick a category</string>
|
||||
|
||||
<string name="report_reason_content_illegal">Illegal content</string>
|
||||
<string name="report_reason_content_illegal_goods">Drugs or other illegal goods</string>
|
||||
<string name="report_reason_content_illegal_extortion">Extortion or blackmail</string>
|
||||
<string name="report_reason_content_illegal_pornography">Revenge or underage pornography</string>
|
||||
<string name="report_reason_content_illegal_hacking">Illegal hacking or cracking</string>
|
||||
<string name="report_reason_content_extreme_violence">Extreme violence, gore or animal cruelty</string>
|
||||
<string name="report_reason_content_promotes_harm">Promotes harm</string>
|
||||
<string name="report_reason_content_unsolicited_spam">Unsolicited advertising or spam</string>
|
||||
<string name="report_reason_content_raid">Raid or spam attack</string>
|
||||
<string name="report_reason_content_spam_abuse">Spam or similar platform abuse</string>
|
||||
<string name="report_reason_content_scams_fraud">Scams or fraud</string>
|
||||
<string name="report_reason_content_malware">Malware or phishing</string>
|
||||
<string name="report_reason_content_harassment">Harassment or cyberbullying</string>
|
||||
<string name="report_reason_content_other">Other</string>
|
||||
|
||||
<string name="report_reason_user_unsolicited_spam">Unsolicited advertising or spam</string>
|
||||
<string name="report_reason_user_spam_abuse">Spam or similar platform abuse</string>
|
||||
<string name="report_reason_user_inappropriate_content">Inappropriate content (like NSFW)</string>
|
||||
<string name="report_reason_user_impersonation">Impersonation</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue