From 8a276d6f1d267c3f3d486683588de42a60c53fc7 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Apr 2026 03:20:50 +0000 Subject: [PATCH 1/2] feat: add 3-dot options menu to video/picture/file feed cards Adds MoreOptionsButton (the same menu used in NoteCompose) to UserCardHeader, shown to the right of TimeAgo. This gives users the same follow/copy/share/bookmark/report actions on video, picture, and file-header feed cards that they have on text notes. https://claude.ai/code/session_01DrsvnguWHdZMgsRqNS8BUz --- .../screen/loggedIn/pictures/PictureCardCompose.kt | 2 +- .../ui/screen/loggedIn/shorts/VideoCardCompose.kt | 2 +- .../screen/loggedIn/video/FileHeaderCardCompose.kt | 2 +- .../ui/screen/loggedIn/video/UserCardHeader.kt | 12 ++++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt index eee0b459c..0d748a45b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt @@ -65,7 +65,7 @@ fun PictureCardCompose( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav) + UserCardHeader(baseNote, accountViewModel, nav, editState) // Image content PictureCardImage(baseNote, event, backgroundColor, accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt index 52bb33796..772712513 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt @@ -69,7 +69,7 @@ fun VideoCardCompose( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav) + UserCardHeader(baseNote, accountViewModel, nav, editState) // Image content VideoCardImage(baseNote, event, backgroundColor, accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt index 95fe58773..2327baa63 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt @@ -68,7 +68,7 @@ fun FileHeaderCardCompose( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav) + UserCardHeader(baseNote, accountViewModel, nav, editState) // Image content FileHeaderCardImage(baseNote, event, backgroundColor, accountViewModel) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt index 87d485d2e..c3dedf30e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt @@ -27,15 +27,19 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.State import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay +import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton import com.vitorpamplona.amethyst.ui.note.elements.TimeAgo +import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size35dp @@ -44,6 +48,7 @@ fun UserCardHeader( baseNote: Note, accountViewModel: AccountViewModel, nav: INav, + editState: State>? = null, ) { Row( modifier = @@ -74,5 +79,12 @@ fun UserCardHeader( } TimeAgo(baseNote) + + MoreOptionsButton( + baseNote = baseNote, + editState = editState, + accountViewModel = accountViewModel, + nav = nav, + ) } } From 3147e39aa43575cc4772ea46412934cd325b5be0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 15 Apr 2026 12:07:46 +0000 Subject: [PATCH 2/2] refactor: drop editState from video/picture/file feed cards These feed events (VideoEvent, PictureEvent, FileHeaderEvent) don't support editing, so there's no editState to observe. Remove the observeEdits calls and the editState parameter from UserCardHeader, and make ReactionsRow's editState parameter nullable so these screens can pass null. https://claude.ai/code/session_01DrsvnguWHdZMgsRqNS8BUz --- .../com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt | 10 +++++----- .../ui/screen/loggedIn/pictures/PictureCardCompose.kt | 6 ++---- .../ui/screen/loggedIn/shorts/VideoCardCompose.kt | 6 ++---- .../ui/screen/loggedIn/video/FileHeaderCardCompose.kt | 6 ++---- .../ui/screen/loggedIn/video/UserCardHeader.kt | 6 +----- 5 files changed, 12 insertions(+), 22 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index a332565d0..95966426c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -197,7 +197,7 @@ fun ReactionsRow( baseNote: Note, showReactionDetail: Boolean, addPadding: Boolean, - editState: State>, + editState: State>?, accountViewModel: AccountViewModel, nav: INav, ) { @@ -219,7 +219,7 @@ private fun InnerReactionRow( showReactionDetail: Boolean, addPadding: Boolean, wantsToSeeReactions: MutableState, - editState: State>, + editState: State>?, accountViewModel: AccountViewModel, nav: INav, ) { @@ -666,7 +666,7 @@ private fun WatchZapAndRenderGallery( @Composable private fun BoostWithDialog( baseNote: Note, - editState: State>, + editState: State>?, grayTint: Color, accountViewModel: AccountViewModel, nav: INav, @@ -682,7 +682,7 @@ private fun BoostWithDialog( Route.NewShortNote( quote = baseNote.idHex, version = - (editState.value as? GenericLoadable.Loaded) + (editState?.value as? GenericLoadable.Loaded) ?.loaded ?.modificationToShow ?.value @@ -704,7 +704,7 @@ private fun BoostWithDialog( baseReplyTo = replyTo?.idHex, fork = baseNote.idHex, version = - (editState.value as? GenericLoadable.Loaded) + (editState?.value as? GenericLoadable.Loaded) ?.loaded ?.modificationToShow ?.value diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt index 0d748a45b..864eaacc8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/pictures/PictureCardCompose.kt @@ -45,7 +45,6 @@ import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.ReactionsRow -import com.vitorpamplona.amethyst.ui.note.observeEdits import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.UserCardHeader import com.vitorpamplona.quartz.nip68Picture.PictureEvent @@ -59,13 +58,12 @@ fun PictureCardCompose( ) { val event = (baseNote.event as? PictureEvent) ?: return val backgroundColor = remember { mutableStateOf(Color.Transparent) } - val editState = observeEdits(baseNote = baseNote, accountViewModel = accountViewModel) Column( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav, editState) + UserCardHeader(baseNote, accountViewModel, nav) // Image content PictureCardImage(baseNote, event, backgroundColor, accountViewModel) @@ -75,7 +73,7 @@ fun PictureCardCompose( baseNote = baseNote, showReactionDetail = true, addPadding = true, - editState = editState, + editState = null, accountViewModel = accountViewModel, nav = nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt index 772712513..ba77fe0b6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/shorts/VideoCardCompose.kt @@ -47,7 +47,6 @@ import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.ReactionsRow -import com.vitorpamplona.amethyst.ui.note.observeEdits import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.video.UserCardHeader import com.vitorpamplona.quartz.nip01Core.core.Event @@ -63,13 +62,12 @@ fun VideoCardCompose( ) { val event = (baseNote.event as? VideoEvent) ?: return val backgroundColor = remember { mutableStateOf(Color.Transparent) } - val editState = observeEdits(baseNote = baseNote, accountViewModel = accountViewModel) Column( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav, editState) + UserCardHeader(baseNote, accountViewModel, nav) // Image content VideoCardImage(baseNote, event, backgroundColor, accountViewModel) @@ -79,7 +77,7 @@ fun VideoCardCompose( baseNote = baseNote, showReactionDetail = true, addPadding = true, - editState = editState, + editState = null, accountViewModel = accountViewModel, nav = nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt index 2327baa63..3b6dca98a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/FileHeaderCardCompose.kt @@ -47,7 +47,6 @@ import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.ZoomableContentView import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.ReactionsRow -import com.vitorpamplona.amethyst.ui.note.observeEdits import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip31Alts.alt @@ -62,13 +61,12 @@ fun FileHeaderCardCompose( ) { val event = (baseNote.event as? FileHeaderEvent) ?: return val backgroundColor = remember { mutableStateOf(Color.Transparent) } - val editState = observeEdits(baseNote = baseNote, accountViewModel = accountViewModel) Column( modifier = Modifier.fillMaxWidth(), ) { // Author header row - UserCardHeader(baseNote, accountViewModel, nav, editState) + UserCardHeader(baseNote, accountViewModel, nav) // Image content FileHeaderCardImage(baseNote, event, backgroundColor, accountViewModel) @@ -78,7 +76,7 @@ fun FileHeaderCardCompose( baseNote = baseNote, showReactionDetail = true, addPadding = true, - editState = editState, + editState = null, accountViewModel = accountViewModel, nav = nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt index c3dedf30e..5169bf2fd 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/UserCardHeader.kt @@ -27,19 +27,16 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.runtime.State import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.model.Note -import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor import com.vitorpamplona.amethyst.ui.note.NoteAuthorPicture import com.vitorpamplona.amethyst.ui.note.NoteUsernameDisplay import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton import com.vitorpamplona.amethyst.ui.note.elements.TimeAgo -import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.Size35dp @@ -48,7 +45,6 @@ fun UserCardHeader( baseNote: Note, accountViewModel: AccountViewModel, nav: INav, - editState: State>? = null, ) { Row( modifier = @@ -82,7 +78,7 @@ fun UserCardHeader( MoreOptionsButton( baseNote = baseNote, - editState = editState, + editState = null, accountViewModel = accountViewModel, nav = nav, )