Merge branch 'feat/android-report-a-story' into 'main'

Report a story on Android, which had no way to

See merge request paulhitt/flamenet-messenger-android!87
This commit was merged in pull request #114.
This commit is contained in:
Paul Hitt
2026-09-07 01:56:06 +00:00
2 changed files with 52 additions and 3 deletions
@@ -4120,7 +4120,13 @@ private fun EditMessageSheet(
* to somebody who may do nothing.
*/
@Composable
private fun ReportSheet(
/**
* ⚠️ Was `private` to this file, which is why the stories feed could not use
* it and Android had no way to report a story at all. Widened rather than
* copied: two report sheets would be two places for the consent wording to
* drift apart, and the consent is the part that matters.
*/
internal fun ReportSheet(
authorName: String,
preview: String,
onDismiss: () -> Unit,
@@ -238,7 +238,7 @@ private fun StoryCard(
}
Spacer(Modifier.height(Space.md))
StoryActions(story, model)
StoryActions(story, model, authorName = author)
}
}
@@ -253,10 +253,18 @@ private fun StoryCard(
* a row of buttons that do nothing is worse than no row.
*/
@Composable
private fun StoryActions(story: Vault.Story, model: MessengerViewModel) {
private fun StoryActions(
story: Vault.Story,
model: MessengerViewModel,
// ⚠️ Passed in rather than resolved here: `StoryCard` already has the
// buddy list and has already done this, and two resolutions of the same
// name are two chances to disagree about who is being reported.
authorName: String = "",
) {
val quick = listOf("❤️", "😂", "😮", "😢", "🔥")
var replying by remember { mutableStateOf(false) }
var muting by remember { mutableStateOf(false) }
var reporting by remember { mutableStateOf(false) }
if (story.mine) {
val tally = model.storyTally(story.id)
@@ -298,6 +306,41 @@ private fun StoryActions(story: Vault.Story, model: MessengerViewModel) {
Spacer(Modifier.size(12.dp))
Text("Mute", fontSize = 13.sp, color = Palette.Mist,
modifier = Modifier.clickable { muting = true }.testTag("story-mute"))
// 🔴 **Reporting a story, which Android could not do.** iOS has had it
// since stories shipped; here `MessengerViewModel.reportStory` was
// written, tested by nothing, and called by no screen. A capability
// with no way in is, for Apple's Guideline 1.2 and Play's UGC policy,
// the same as no capability — and a story is the most public thing
// this app carries, so it is the surface those rules are aimed at.
//
// ⚠️ Not on your own story. Reporting yourself to the operator is not
// something anybody means to do, and offering it invites a misfire.
if (!story.mine) {
Spacer(Modifier.size(12.dp))
Text("Report", fontSize = 13.sp, color = Palette.Mist,
modifier = Modifier.clickable { reporting = true }
.testTag("story-report"))
}
}
if (reporting) {
// ⚠️ The SAME sheet a message report uses, deliberately. Two sheets
// would be two places for the consent wording to drift apart, and the
// consent — that sending a copy hands the operator something readable —
// is the part that matters.
ReportSheet(
authorName = authorName.ifBlank { "this person" },
preview = story.caption,
onDismiss = { reporting = false },
onSend = { reason, includeContent, note ->
model.reportStory(story, reason, includeContent, note)
reporting = false
},
onBlock = {
model.setBlocked(story.authorId, true)
reporting = false
},
)
}
if (replying) {