mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
Merge pull request #4288 from vitorpamplona/claude/charming-lamport-klffdw
Add NIP-34 Git status event rendering support
This commit is contained in:
+4
@@ -186,6 +186,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.types.RenderFhirResource
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderFundraiser
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGeocache
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGeocacheFoundLog
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGitStatusEvent
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGoal
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderHighlight
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderInteractiveStory
|
||||
@@ -332,6 +333,7 @@ import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestUpdateEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
@@ -1026,6 +1028,8 @@ private fun FullBleedNoteCompose(
|
||||
RenderGitPullRequestEvent(baseNote, makeItShort = false, canPreview = true, quotesLeft = 3, backgroundColor = backgroundColor, accountViewModel = accountViewModel, nav = nav)
|
||||
} else if (noteEvent is GitPullRequestUpdateEvent) {
|
||||
RenderGitPullRequestUpdateEvent(baseNote, makeItShort = false, canPreview = true, quotesLeft = 3, backgroundColor = backgroundColor, accountViewModel = accountViewModel, nav = nav)
|
||||
} else if (noteEvent is GitStatusEvent) {
|
||||
RenderGitStatusEvent(baseNote, quotesLeft = 3, backgroundColor, accountViewModel, nav)
|
||||
} else if (noteEvent is AppDefinitionEvent) {
|
||||
RenderAppDefinition(baseNote, accountViewModel, nav)
|
||||
} else if (noteEvent is AppRecommendationEvent) {
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip34Git.status.GitStatusDraftEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusOpenEvent
|
||||
|
||||
private fun GitStatusEvent.statusKind(): StatusKind =
|
||||
fun GitStatusEvent.statusKind(): StatusKind =
|
||||
when (this) {
|
||||
is GitStatusAppliedEvent -> StatusKind.APPLIED
|
||||
is GitStatusClosedEvent -> StatusKind.CLOSED
|
||||
|
||||
+6
@@ -194,6 +194,7 @@ import com.vitorpamplona.amethyst.commons.ui.note.types.RenderFhirResource
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderFundraiser
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGeocache
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGeocacheFoundLog
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGitStatusEvent
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderGoal
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderHighlight
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.types.RenderInteractiveStory
|
||||
@@ -362,6 +363,7 @@ import com.vitorpamplona.quartz.nip34Git.patch.GitPatchEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.pr.GitPullRequestUpdateEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.repository.GitRepositoryEvent
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentCommentEvent
|
||||
import com.vitorpamplona.quartz.nip35Torrents.TorrentEvent
|
||||
import com.vitorpamplona.quartz.nip37Drafts.DraftWrapEvent
|
||||
@@ -1393,6 +1395,10 @@ private fun RenderNoteRow(
|
||||
)
|
||||
}
|
||||
|
||||
is GitStatusEvent -> {
|
||||
RenderGitStatusEvent(baseNote, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
|
||||
is EncryptedDmEvent -> {
|
||||
RenderPrivateMessage(
|
||||
baseNote,
|
||||
|
||||
+1
-1
@@ -89,7 +89,7 @@ fun RenderBolt12Zap(
|
||||
},
|
||||
)
|
||||
|
||||
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
RenderTargetNote(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
|
||||
amountSats?.let { ActivityAmountRow(PlatformNumberFormatter().format(it), orange) }
|
||||
|
||||
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.ui.note.types
|
||||
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.nip34Git.ui.statusKind
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.GitStatusPill
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.StdVertSpacer
|
||||
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nip34Git.status.GitStatusEvent
|
||||
|
||||
/**
|
||||
* Renders a NIP-34 status event (kinds 1630-1633). These usually carry an
|
||||
* empty `content`, so the text fallback drew a blank note: show the new
|
||||
* status as a pill, the optional comment, and the issue/patch/PR it
|
||||
* targets (linked through the event's marked-`root` `e` tag) quoted below.
|
||||
*/
|
||||
@Composable
|
||||
fun RenderGitStatusEvent(
|
||||
note: Note,
|
||||
quotesLeft: Int,
|
||||
backgroundColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val event = note.event as? GitStatusEvent ?: return
|
||||
val kind = remember(event) { event.statusKind() }
|
||||
|
||||
GitStatusPill(kind)
|
||||
|
||||
if (event.content.isNotBlank()) {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Text(
|
||||
text = event.content,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
}
|
||||
|
||||
if (note.replyTo?.lastOrNull() != null) {
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
RenderTargetNote(note, quotesLeft, backgroundColor, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -93,7 +93,7 @@ fun RenderNutzap(
|
||||
},
|
||||
)
|
||||
|
||||
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
RenderTargetNote(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
|
||||
ActivityAmountRow(showAmount(BigDecimal(nutzapEvent.claimedSatsTotal())), orange)
|
||||
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ fun RenderOnchainZap(
|
||||
nav = nav,
|
||||
)
|
||||
|
||||
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
RenderTargetNote(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
|
||||
AmountRow(sats = sats, orange = orange)
|
||||
|
||||
|
||||
+1
-1
@@ -81,6 +81,6 @@ fun RenderReaction(
|
||||
},
|
||||
)
|
||||
|
||||
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
RenderTargetNote(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Vitor Pamplona
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.commons.ui.note.types
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.vitorpamplona.amethyst.commons.model.Note
|
||||
import com.vitorpamplona.amethyst.commons.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.NoteCompose
|
||||
import com.vitorpamplona.amethyst.commons.viewmodels.AccountViewModel
|
||||
|
||||
/**
|
||||
* Quotes the note that [note] acts on (the last entry of its `replyTo`) as a
|
||||
* short embedded card: the post a zap or reaction targets, the issue/patch/PR
|
||||
* a git status changes, and so on.
|
||||
*/
|
||||
@Composable
|
||||
fun RenderTargetNote(
|
||||
note: Note,
|
||||
quotesLeft: Int,
|
||||
backgroundColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
note.replyTo?.lastOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = true,
|
||||
makeItShort = true,
|
||||
unPackReply = ReplyRenderType.NONE,
|
||||
quotesLeft = quotesLeft - 1,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
+1
-29
@@ -52,7 +52,6 @@ import com.vitorpamplona.amethyst.commons.ui.note.ActivityCardFrame
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.ActivityHeaderRow
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.CrossfadeToDisplayComment
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.DisplayBlankAuthor
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.NoteCompose
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.UserPicture
|
||||
import com.vitorpamplona.amethyst.commons.ui.note.ZapIcon
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.Size20Modifier
|
||||
@@ -70,33 +69,6 @@ import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/**
|
||||
* Shows the post a zap targets above the transfer card, mirroring how
|
||||
* reactions and reposts embed their target.
|
||||
*/
|
||||
@Composable
|
||||
fun RenderZappedPost(
|
||||
zapNote: Note,
|
||||
quotesLeft: Int,
|
||||
backgroundColor: MutableState<Color>,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
zapNote.replyTo?.lastOrNull()?.let {
|
||||
NoteCompose(
|
||||
it,
|
||||
modifier = Modifier,
|
||||
isBoostedNote = true,
|
||||
makeItShort = true,
|
||||
unPackReply = ReplyRenderType.NONE,
|
||||
quotesLeft = quotesLeft - 1,
|
||||
parentBackgroundColor = backgroundColor,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RenderZapReceipt(
|
||||
note: Note,
|
||||
@@ -155,7 +127,7 @@ fun RenderZapReceiptCard(
|
||||
},
|
||||
)
|
||||
|
||||
RenderZappedPost(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
RenderTargetNote(note, quotesLeft, cardBackground, accountViewModel, nav)
|
||||
|
||||
card.amount?.let { ActivityAmountRow(it, orange) }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user