mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-29 11:11:44 +01:00
Creates links to njump when events can't be found on Amethyst
This commit is contained in:
parent
a8a3c94115
commit
83f1e523ea
@ -25,6 +25,7 @@ import android.util.LruCache
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
import com.vitorpamplona.amethyst.ui.note.njumpLink
|
||||
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||
import com.vitorpamplona.ammolite.relays.Relay
|
||||
import com.vitorpamplona.ammolite.relays.RelayStats
|
||||
@ -82,7 +83,7 @@ class AntiSpamFilter {
|
||||
logOffender(hash, event)
|
||||
|
||||
if (relay != null) {
|
||||
RelayStats.newSpam(relay.url, "https://njump.me/${Nip19Bech32.createNEvent(event.id, event.pubKey, event.kind, relay.url)}")
|
||||
RelayStats.newSpam(relay.url, njumpLink(Nip19Bech32.createNEvent(event.id, event.pubKey, event.kind, relay.url)))
|
||||
}
|
||||
|
||||
liveSpam.invalidateData()
|
||||
|
@ -41,6 +41,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.takeOrElse
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.Placeholder
|
||||
import androidx.compose.ui.text.PlaceholderVerticalAlign
|
||||
@ -59,7 +60,7 @@ import coil.compose.AsyncImage
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.note.LoadChannel
|
||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
||||
import com.vitorpamplona.amethyst.ui.note.njumpLink
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.Nip19Bech32
|
||||
@ -80,12 +81,12 @@ fun ClickableRoute(
|
||||
nav: (String) -> Unit,
|
||||
) {
|
||||
when (val entity = nip19.entity) {
|
||||
is Nip19Bech32.NPub -> DisplayUser(entity.hex, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NProfile -> DisplayUser(entity.hex, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.Note -> DisplayEvent(entity.hex, null, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NEvent -> DisplayEvent(entity.hex, entity.kind, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NPub -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NProfile -> DisplayUser(entity.hex, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.Note -> DisplayEvent(entity.hex, null, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NEvent -> DisplayEvent(entity.hex, entity.kind, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NEmbed -> LoadAndDisplayEvent(entity.event, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NAddress -> DisplayAddress(entity, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NAddress -> DisplayAddress(entity, nip19.nip19raw, nip19.additionalChars, accountViewModel, nav)
|
||||
is Nip19Bech32.NRelay -> {
|
||||
Text(word)
|
||||
}
|
||||
@ -127,11 +128,16 @@ private fun LoadAndDisplayEvent(
|
||||
if (it != null) {
|
||||
DisplayNoteLink(it, event.id, event.kind, additionalChars, accountViewModel, nav)
|
||||
} else {
|
||||
val externalLink = event.toNIP19()
|
||||
val uri = LocalUriHandler.current
|
||||
|
||||
CreateClickableText(
|
||||
clickablePart = remember(event.id) { "@${event.toNIP19()}" },
|
||||
clickablePart = "@$externalLink",
|
||||
suffix = additionalChars,
|
||||
route = remember(event.id) { "Event/${event.id}" },
|
||||
nav = nav,
|
||||
maxLines = 1,
|
||||
onClick = {
|
||||
runCatching { uri.openUri(njumpLink(externalLink)) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -141,6 +147,7 @@ private fun LoadAndDisplayEvent(
|
||||
fun DisplayEvent(
|
||||
hex: HexKey,
|
||||
kind: Int?,
|
||||
nip19: String,
|
||||
additionalChars: String?,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit,
|
||||
@ -149,11 +156,16 @@ fun DisplayEvent(
|
||||
if (it != null) {
|
||||
DisplayNoteLink(it, hex, kind, additionalChars, accountViewModel, nav)
|
||||
} else {
|
||||
val externalLink = njumpLink(nip19)
|
||||
val uri = LocalUriHandler.current
|
||||
|
||||
CreateClickableText(
|
||||
clickablePart = remember(hex) { "@${hex.toShortenHex()}" },
|
||||
clickablePart = remember(nip19) { "@$nip19" },
|
||||
suffix = additionalChars,
|
||||
route = remember(hex) { "Event/$hex" },
|
||||
nav = nav,
|
||||
maxLines = 1,
|
||||
onClick = {
|
||||
runCatching { uri.openUri(externalLink) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -218,6 +230,7 @@ private fun DisplayNoteLink(
|
||||
@Composable
|
||||
private fun DisplayAddress(
|
||||
nip19: Nip19Bech32.NAddress,
|
||||
originalNip19: String,
|
||||
additionalChars: String?,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit,
|
||||
@ -245,21 +258,23 @@ private fun DisplayAddress(
|
||||
}
|
||||
|
||||
if (noteBase == null) {
|
||||
if (additionalChars != null) {
|
||||
Text(
|
||||
remember { "@${nip19.atag}$additionalChars" },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
remember { "@${nip19.atag}" },
|
||||
)
|
||||
}
|
||||
val uri = LocalUriHandler.current
|
||||
|
||||
CreateClickableText(
|
||||
clickablePart = "@$originalNip19",
|
||||
suffix = additionalChars,
|
||||
maxLines = 1,
|
||||
onClick = {
|
||||
runCatching { uri.openUri(njumpLink(originalNip19)) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
public fun DisplayUser(
|
||||
userHex: HexKey,
|
||||
originalNip19: String,
|
||||
additionalChars: String?,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: (String) -> Unit,
|
||||
@ -280,15 +295,16 @@ public fun DisplayUser(
|
||||
userBase?.let { RenderUserAsClickableText(it, additionalChars, nav) }
|
||||
|
||||
if (userBase == null) {
|
||||
if (additionalChars != null) {
|
||||
Text(
|
||||
remember { "@${userHex}$additionalChars" },
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
remember { "@$userHex" },
|
||||
)
|
||||
}
|
||||
val uri = LocalUriHandler.current
|
||||
|
||||
CreateClickableText(
|
||||
clickablePart = "@$originalNip19",
|
||||
suffix = additionalChars,
|
||||
maxLines = 1,
|
||||
onClick = {
|
||||
runCatching { uri.openUri(njumpLink(originalNip19)) }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,6 +336,26 @@ fun CreateClickableText(
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
route: String,
|
||||
nav: (String) -> Unit,
|
||||
) {
|
||||
CreateClickableText(
|
||||
clickablePart,
|
||||
suffix,
|
||||
maxLines,
|
||||
overrideColor,
|
||||
fontWeight,
|
||||
fontSize,
|
||||
) { nav(route) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CreateClickableText(
|
||||
clickablePart: String,
|
||||
suffix: String?,
|
||||
maxLines: Int = Int.MAX_VALUE,
|
||||
overrideColor: Color? = null,
|
||||
fontWeight: FontWeight? = null,
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
onClick: (Int) -> Unit,
|
||||
) {
|
||||
val primaryColor = MaterialTheme.colorScheme.primary
|
||||
val onBackgroundColor = MaterialTheme.colorScheme.onBackground
|
||||
@ -351,7 +387,8 @@ fun CreateClickableText(
|
||||
ClickableText(
|
||||
text = text,
|
||||
maxLines = maxLines,
|
||||
onClick = { nav(route) },
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,8 @@ class MarkdownMediaRenderer(
|
||||
}
|
||||
} else if (loadedLink?.nip19 != null) {
|
||||
when (val entity = loadedLink.nip19.entity) {
|
||||
is Nip19Bech32.NPub -> renderObservableUser(entity.hex, richTextStringBuilder)
|
||||
is Nip19Bech32.NProfile -> renderObservableUser(entity.hex, richTextStringBuilder)
|
||||
is Nip19Bech32.NPub -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder)
|
||||
is Nip19Bech32.NProfile -> renderObservableUser(entity.hex, loadedLink.nip19.nip19raw, richTextStringBuilder)
|
||||
is Nip19Bech32.Note -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder)
|
||||
is Nip19Bech32.NEvent -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder)
|
||||
is Nip19Bech32.NEmbed -> renderObservableShortNoteUri(loadedLink, uri, richTextStringBuilder)
|
||||
@ -201,10 +201,11 @@ class MarkdownMediaRenderer(
|
||||
|
||||
fun renderObservableUser(
|
||||
userHex: String,
|
||||
nip19: String,
|
||||
richTextStringBuilder: RichTextString.Builder,
|
||||
) {
|
||||
renderInline(richTextStringBuilder) {
|
||||
DisplayUser(userHex, null, accountViewModel, nav)
|
||||
DisplayUser(userHex, nip19, null, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,11 @@ private fun lightenColor(
|
||||
}
|
||||
|
||||
val externalLinkForUser = { user: User ->
|
||||
"https://njump.me/${user.toNProfile()}"
|
||||
njumpLink(user.toNProfile())
|
||||
}
|
||||
|
||||
val njumpLink = { nip19BechAddress: String ->
|
||||
"https://njump.me/$nip19BechAddress"
|
||||
}
|
||||
|
||||
val externalLinkForNote = { note: Note ->
|
||||
@ -119,17 +123,17 @@ val externalLinkForNote = { note: Note ->
|
||||
if (note.event?.getReward() != null) {
|
||||
"https://nostrbounties.com/b/${note.address().toNAddr()}"
|
||||
} else if (note.event is PeopleListEvent) {
|
||||
"https://listr.lol/a/${note.address()?.toNAddr()}"
|
||||
"https://listr.lol/a/${note.address().toNAddr()}"
|
||||
} else if (note.event is AudioTrackEvent) {
|
||||
"https://zapstr.live/?track=${note.address()?.toNAddr()}"
|
||||
"https://zapstr.live/?track=${note.address().toNAddr()}"
|
||||
} else {
|
||||
"https://njump.me/${note.address()?.toNAddr()}"
|
||||
njumpLink(note.address().toNAddr())
|
||||
}
|
||||
} else {
|
||||
if (note.event is FileHeaderEvent) {
|
||||
"https://filestr.vercel.app/e/${note.toNEvent()}"
|
||||
} else {
|
||||
"https://njump.me/${note.toNEvent()}"
|
||||
njumpLink(note.toNEvent())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +257,7 @@ fun DisplayEntryForNote(
|
||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
||||
)
|
||||
} else {
|
||||
DisplayEvent(noteEvent.id, noteEvent.kind, "", accountViewModel, nav)
|
||||
DisplayEvent(noteEvent.id, noteEvent.kind, noteEvent.toNIP19(), null, accountViewModel, nav)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,7 @@ object Nip19Bech32 {
|
||||
@Immutable
|
||||
data class ParseReturn(
|
||||
val entity: Entity,
|
||||
val nip19raw: String,
|
||||
val additionalChars: String? = null,
|
||||
)
|
||||
|
||||
@ -138,7 +139,8 @@ object Nip19Bech32 {
|
||||
additionalChars: String?,
|
||||
): ParseReturn? =
|
||||
try {
|
||||
val bytes = (type + key).bechToBytes()
|
||||
val nip19 = (type + key)
|
||||
val bytes = nip19.bechToBytes()
|
||||
|
||||
when (type.lowercase()) {
|
||||
"nsec1" -> nsec(bytes)
|
||||
@ -151,7 +153,7 @@ object Nip19Bech32 {
|
||||
"nembed1" -> nembed(bytes)
|
||||
else -> null
|
||||
}?.let {
|
||||
ParseReturn(it, additionalChars)
|
||||
ParseReturn(it, nip19, additionalChars)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
Log.w("NIP19 Parser", "Issue trying to Decode NIP19 $key: ${e.message}", e)
|
||||
|
Loading…
x
Reference in New Issue
Block a user