mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-17 21:31:57 +01:00
Updates NIP-56 to the newest tag structure for Quartz
This commit is contained in:
parent
5766bb1887
commit
b017e03728
@ -149,6 +149,7 @@ import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
|
|||||||
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
import com.vitorpamplona.quartz.nip51Lists.MuteListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
import com.vitorpamplona.quartz.nip51Lists.PeopleListEvent
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
import com.vitorpamplona.quartz.nip57Zaps.splits.ZapSplitSetup
|
||||||
@ -1616,18 +1617,18 @@ class Account(
|
|||||||
|
|
||||||
suspend fun report(
|
suspend fun report(
|
||||||
note: Note,
|
note: Note,
|
||||||
type: ReportEvent.ReportType,
|
type: ReportType,
|
||||||
content: String = "",
|
content: String = "",
|
||||||
) {
|
) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
if (note.hasReacted(userProfile(), "⚠️")) {
|
if (note.hasReport(userProfile(), type)) {
|
||||||
// has already liked this note
|
// has already reported this note
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
note.event?.let {
|
note.event?.let {
|
||||||
ReportEvent.create(it, type, signer, content) {
|
signer.sign(ReportEvent.build(it, type)) {
|
||||||
Amethyst.instance.client.send(it)
|
Amethyst.instance.client.send(it)
|
||||||
LocalCache.justConsume(it, null)
|
LocalCache.justConsume(it, null)
|
||||||
}
|
}
|
||||||
@ -1636,7 +1637,7 @@ class Account(
|
|||||||
|
|
||||||
suspend fun report(
|
suspend fun report(
|
||||||
user: User,
|
user: User,
|
||||||
type: ReportEvent.ReportType,
|
type: ReportType,
|
||||||
) {
|
) {
|
||||||
if (!isWriteable()) return
|
if (!isWriteable()) return
|
||||||
|
|
||||||
@ -1645,7 +1646,8 @@ class Account(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ReportEvent.create(user.pubkeyHex, type, signer) {
|
val template = ReportEvent.build(user.pubkeyHex, type)
|
||||||
|
signer.sign(template) {
|
||||||
Amethyst.instance.client.send(it)
|
Amethyst.instance.client.send(it)
|
||||||
LocalCache.justConsume(it, null)
|
LocalCache.justConsume(it, null)
|
||||||
}
|
}
|
||||||
|
@ -695,8 +695,8 @@ object LocalCache {
|
|||||||
event.originalPost().mapNotNull { checkGetOrCreateNote(it) } +
|
event.originalPost().mapNotNull { checkGetOrCreateNote(it) } +
|
||||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
||||||
is ReportEvent ->
|
is ReportEvent ->
|
||||||
event.reportedPost().mapNotNull { checkGetOrCreateNote(it.key) } +
|
event.reportedPost().mapNotNull { checkGetOrCreateNote(it.eventId) } +
|
||||||
event.taggedAddresses().map { getOrCreateAddressableNote(it) }
|
event.reportedAddresses().map { getOrCreateAddressableNote(it.address) }
|
||||||
is ChannelMessageEvent ->
|
is ChannelMessageEvent ->
|
||||||
event
|
event
|
||||||
.tagsWithoutCitations()
|
.tagsWithoutCitations()
|
||||||
@ -1342,7 +1342,7 @@ object LocalCache {
|
|||||||
// Already processed this event.
|
// Already processed this event.
|
||||||
if (note.event != null) return
|
if (note.event != null) return
|
||||||
|
|
||||||
val mentions = event.reportedAuthor().mapNotNull { checkGetOrCreateUser(it.key) }
|
val mentions = event.reportedAuthor().mapNotNull { checkGetOrCreateUser(it.pubkey) }
|
||||||
val repliesTo = computeReplyTo(event)
|
val repliesTo = computeReplyTo(event)
|
||||||
|
|
||||||
note.loadEvent(event, author, repliesTo)
|
note.loadEvent(event, author, repliesTo)
|
||||||
@ -2218,7 +2218,7 @@ object LocalCache {
|
|||||||
}
|
}
|
||||||
if (noteEvent is ReportEvent) {
|
if (noteEvent is ReportEvent) {
|
||||||
noteEvent.reportedAuthor().mapNotNull {
|
noteEvent.reportedAuthor().mapNotNull {
|
||||||
val author = getUserIfExists(it.key)
|
val author = getUserIfExists(it.pubkey)
|
||||||
author?.removeReport(note)
|
author?.removeReport(note)
|
||||||
author?.clearEOSE()
|
author?.clearEOSE()
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,8 @@ import com.vitorpamplona.quartz.nip47WalletConnect.LnZapPaymentResponseEvent
|
|||||||
import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse
|
import com.vitorpamplona.quartz.nip47WalletConnect.PayInvoiceSuccessResponse
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
|
import com.vitorpamplona.quartz.nip59Giftwrap.WrappedEvent
|
||||||
@ -717,6 +719,15 @@ open class Note(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun hasReport(
|
||||||
|
loggedIn: User,
|
||||||
|
type: ReportType,
|
||||||
|
): Boolean =
|
||||||
|
reports[loggedIn]?.firstOrNull {
|
||||||
|
it.event is ReportEvent &&
|
||||||
|
(it.event as ReportEvent).reportedAuthor().any { it.type == type }
|
||||||
|
} != null
|
||||||
|
|
||||||
fun hasPledgeBy(user: User): Boolean =
|
fun hasPledgeBy(user: User): Boolean =
|
||||||
replies
|
replies
|
||||||
.filter { it.event?.hasAdditionalReward() ?: false }
|
.filter { it.event?.hasAdditionalReward() ?: false }
|
||||||
|
@ -46,6 +46,7 @@ import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile
|
|||||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||||
import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent
|
import com.vitorpamplona.quartz.nip51Lists.BookmarkListEvent
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||||
import com.vitorpamplona.quartz.utils.DualCase
|
import com.vitorpamplona.quartz.utils.DualCase
|
||||||
@ -357,11 +358,11 @@ class User(
|
|||||||
|
|
||||||
fun hasReport(
|
fun hasReport(
|
||||||
loggedIn: User,
|
loggedIn: User,
|
||||||
type: ReportEvent.ReportType,
|
type: ReportType,
|
||||||
): Boolean =
|
): Boolean =
|
||||||
reports[loggedIn]?.firstOrNull {
|
reports[loggedIn]?.firstOrNull {
|
||||||
it.event is ReportEvent &&
|
it.event is ReportEvent &&
|
||||||
(it.event as ReportEvent).reportedAuthor().any { it.reportType == type }
|
(it.event as ReportEvent).reportedAuthor().any { it.type == type }
|
||||||
} != null
|
} != null
|
||||||
|
|
||||||
fun containsAny(hiddenWordsCase: List<DualCase>): Boolean {
|
fun containsAny(hiddenWordsCase: List<DualCase>): Boolean {
|
||||||
|
@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
|||||||
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
import com.vitorpamplona.amethyst.ui.theme.replyModifier
|
||||||
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
import com.vitorpamplona.quartz.nip02FollowList.EmptyTagList
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RenderReport(
|
fun RenderReport(
|
||||||
@ -52,16 +53,17 @@ fun RenderReport(
|
|||||||
val reportType =
|
val reportType =
|
||||||
base
|
base
|
||||||
.map {
|
.map {
|
||||||
when (it.reportType) {
|
when (it.type) {
|
||||||
ReportEvent.ReportType.EXPLICIT -> stringRes(R.string.explicit_content)
|
ReportType.EXPLICIT -> stringRes(R.string.explicit_content)
|
||||||
ReportEvent.ReportType.NUDITY -> stringRes(R.string.nudity)
|
ReportType.NUDITY -> stringRes(R.string.nudity)
|
||||||
ReportEvent.ReportType.PROFANITY -> stringRes(R.string.profanity_hateful_speech)
|
ReportType.PROFANITY -> stringRes(R.string.profanity_hateful_speech)
|
||||||
ReportEvent.ReportType.SPAM -> stringRes(R.string.spam)
|
ReportType.SPAM -> stringRes(R.string.spam)
|
||||||
ReportEvent.ReportType.IMPERSONATION -> stringRes(R.string.impersonation)
|
ReportType.IMPERSONATION -> stringRes(R.string.impersonation)
|
||||||
ReportEvent.ReportType.ILLEGAL -> stringRes(R.string.illegal_behavior)
|
ReportType.ILLEGAL -> stringRes(R.string.illegal_behavior)
|
||||||
ReportEvent.ReportType.MALWARE -> stringRes(R.string.malware)
|
ReportType.MALWARE -> stringRes(R.string.malware)
|
||||||
ReportEvent.ReportType.MOD -> stringRes(R.string.mod)
|
ReportType.MOD -> stringRes(R.string.mod)
|
||||||
ReportEvent.ReportType.OTHER -> stringRes(R.string.other)
|
ReportType.OTHER -> stringRes(R.string.other)
|
||||||
|
null -> stringRes(R.string.other)
|
||||||
}
|
}
|
||||||
}.toSet()
|
}.toSet()
|
||||||
.joinToString(", ")
|
.joinToString(", ")
|
||||||
|
@ -102,7 +102,7 @@ import com.vitorpamplona.quartz.nip37Drafts.DraftEvent
|
|||||||
import com.vitorpamplona.quartz.nip47WalletConnect.Response
|
import com.vitorpamplona.quartz.nip47WalletConnect.Response
|
||||||
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
import com.vitorpamplona.quartz.nip50Search.SearchRelayListEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
|
import com.vitorpamplona.quartz.nip51Lists.GeneralListEvent
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||||
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
import com.vitorpamplona.quartz.nip57Zaps.zapraiser.zapraiserAmount
|
||||||
@ -741,7 +741,7 @@ class AccountViewModel(
|
|||||||
|
|
||||||
fun report(
|
fun report(
|
||||||
note: Note,
|
note: Note,
|
||||||
type: ReportEvent.ReportType,
|
type: ReportType,
|
||||||
content: String = "",
|
content: String = "",
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch(Dispatchers.IO) { account.report(note, type, content) }
|
viewModelScope.launch(Dispatchers.IO) { account.report(note, type, content) }
|
||||||
@ -749,7 +749,7 @@ class AccountViewModel(
|
|||||||
|
|
||||||
fun report(
|
fun report(
|
||||||
user: User,
|
user: User,
|
||||||
type: ReportEvent.ReportType,
|
type: ReportType,
|
||||||
) {
|
) {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
account.report(user, type)
|
account.report(user, type)
|
||||||
|
@ -63,7 +63,7 @@ import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon
|
|||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.amethyst.ui.theme.WarningColor
|
import com.vitorpamplona.amethyst.ui.theme.WarningColor
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@ -75,13 +75,13 @@ fun ReportNoteDialog(
|
|||||||
) {
|
) {
|
||||||
val reportTypes =
|
val reportTypes =
|
||||||
listOf(
|
listOf(
|
||||||
Pair(ReportEvent.ReportType.SPAM, stringRes(R.string.report_dialog_spam)),
|
Pair(ReportType.SPAM, stringRes(R.string.report_dialog_spam)),
|
||||||
Pair(ReportEvent.ReportType.PROFANITY, stringRes(R.string.report_dialog_profanity)),
|
Pair(ReportType.PROFANITY, stringRes(R.string.report_dialog_profanity)),
|
||||||
Pair(ReportEvent.ReportType.IMPERSONATION, stringRes(R.string.report_dialog_impersonation)),
|
Pair(ReportType.IMPERSONATION, stringRes(R.string.report_dialog_impersonation)),
|
||||||
Pair(ReportEvent.ReportType.NUDITY, stringRes(R.string.report_dialog_nudity)),
|
Pair(ReportType.NUDITY, stringRes(R.string.report_dialog_nudity)),
|
||||||
Pair(ReportEvent.ReportType.ILLEGAL, stringRes(R.string.report_dialog_illegal)),
|
Pair(ReportType.ILLEGAL, stringRes(R.string.report_dialog_illegal)),
|
||||||
Pair(ReportEvent.ReportType.MALWARE, stringRes(R.string.report_malware)),
|
Pair(ReportType.MALWARE, stringRes(R.string.report_malware)),
|
||||||
Pair(ReportEvent.ReportType.MOD, stringRes(R.string.report_mod)),
|
Pair(ReportType.MOD, stringRes(R.string.report_mod)),
|
||||||
)
|
)
|
||||||
|
|
||||||
val reasonOptions = remember { reportTypes.map { TitleExplainer(it.second) }.toImmutableList() }
|
val reasonOptions = remember { reportTypes.map { TitleExplainer(it.second) }.toImmutableList() }
|
||||||
|
@ -36,7 +36,7 @@ import com.vitorpamplona.amethyst.ui.note.externalLinkForUser
|
|||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun UserProfileDropDownMenu(
|
fun UserProfileDropDownMenu(
|
||||||
@ -108,42 +108,42 @@ fun UserProfileDropDownMenu(
|
|||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(id = R.string.report_spam_scam)) },
|
text = { Text(stringRes(id = R.string.report_spam_scam)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.SPAM)
|
accountViewModel.report(user, ReportType.SPAM)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(R.string.report_hateful_speech)) },
|
text = { Text(stringRes(R.string.report_hateful_speech)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.PROFANITY)
|
accountViewModel.report(user, ReportType.PROFANITY)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(id = R.string.report_impersonation)) },
|
text = { Text(stringRes(id = R.string.report_impersonation)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.IMPERSONATION)
|
accountViewModel.report(user, ReportType.IMPERSONATION)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(R.string.report_nudity_porn)) },
|
text = { Text(stringRes(R.string.report_nudity_porn)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.NUDITY)
|
accountViewModel.report(user, ReportType.NUDITY)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(id = R.string.report_illegal_behaviour)) },
|
text = { Text(stringRes(id = R.string.report_illegal_behaviour)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.ILLEGAL)
|
accountViewModel.report(user, ReportType.ILLEGAL)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(
|
||||||
text = { Text(stringRes(id = R.string.report_malware)) },
|
text = { Text(stringRes(id = R.string.report_malware)) },
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.report(user, ReportEvent.ReportType.MALWARE)
|
accountViewModel.report(user, ReportType.MALWARE)
|
||||||
onDismiss()
|
onDismiss()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -25,14 +25,15 @@ import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
|||||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate
|
||||||
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
import com.vitorpamplona.quartz.nip31Alts.AltTag
|
||||||
|
import com.vitorpamplona.quartz.nip31Alts.alt
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.DefaultReportTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAddressTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAuthorTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedEventTag
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
|
||||||
@Immutable data class ReportedKey(
|
|
||||||
val key: String,
|
|
||||||
val reportType: ReportEvent.ReportType,
|
|
||||||
)
|
|
||||||
|
|
||||||
// NIP 56 event.
|
// NIP 56 event.
|
||||||
@Immutable
|
@Immutable
|
||||||
class ReportEvent(
|
class ReportEvent(
|
||||||
@ -43,48 +44,35 @@ class ReportEvent(
|
|||||||
content: String,
|
content: String,
|
||||||
sig: HexKey,
|
sig: HexKey,
|
||||||
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
) : Event(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||||
|
@Transient
|
||||||
|
private var defaultType: ReportType? = null
|
||||||
|
|
||||||
|
private fun defaultReportTypes() = tags.mapNotNull(DefaultReportTag::parse)
|
||||||
|
|
||||||
private fun defaultReportType(): ReportType {
|
private fun defaultReportType(): ReportType {
|
||||||
|
defaultType?.let { return it }
|
||||||
|
|
||||||
// Works with old and new structures for report.
|
// Works with old and new structures for report.
|
||||||
var reportType =
|
var reportType = defaultReportTypes().firstOrNull()
|
||||||
tags
|
|
||||||
.filter { it.firstOrNull() == "report" }
|
|
||||||
.mapNotNull { it.getOrNull(1) }
|
|
||||||
.map { ReportType.valueOf(it.uppercase()) }
|
|
||||||
.firstOrNull()
|
|
||||||
if (reportType == null) {
|
if (reportType == null) {
|
||||||
reportType =
|
reportType = tags.mapNotNull { it.getOrNull(2) }.map { ReportType.parseOrNull(it, emptyArray()) }.firstOrNull()
|
||||||
tags.mapNotNull { it.getOrNull(2) }.map { ReportType.valueOf(it.uppercase()) }.firstOrNull()
|
|
||||||
}
|
}
|
||||||
if (reportType == null) {
|
if (reportType == null) {
|
||||||
reportType = ReportType.SPAM
|
reportType = ReportType.SPAM
|
||||||
}
|
}
|
||||||
|
defaultType = reportType
|
||||||
return reportType
|
return reportType
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportedPost() =
|
fun reportedPost() = tags.mapNotNull { ReportedEventTag.parse(it, defaultReportType()) }
|
||||||
tags
|
|
||||||
.filter { it.size > 1 && it[0] == "e" }
|
|
||||||
.map {
|
|
||||||
ReportedKey(
|
|
||||||
it[1],
|
|
||||||
it.getOrNull(2)?.uppercase()?.let { it1 -> ReportType.valueOf(it1) }
|
|
||||||
?: defaultReportType(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reportedAuthor() =
|
fun reportedAddresses() = tags.mapNotNull { ReportedAddressTag.parse(it, defaultReportType()) }
|
||||||
tags
|
|
||||||
.filter { it.size > 1 && it[0] == "p" }
|
fun reportedAuthor() = tags.mapNotNull { ReportedAuthorTag.parse(it, defaultReportType()) }
|
||||||
.map {
|
|
||||||
ReportedKey(
|
|
||||||
it[1],
|
|
||||||
it.getOrNull(2)?.uppercase()?.let { it1 -> ReportType.valueOf(it1) }
|
|
||||||
?: defaultReportType(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KIND = 1984
|
const val KIND = 1984
|
||||||
|
const val ALT_PREFIX = "Report for "
|
||||||
|
|
||||||
fun create(
|
fun create(
|
||||||
reportedPost: Event,
|
reportedPost: Event,
|
||||||
@ -108,32 +96,27 @@ class ReportEvent(
|
|||||||
signer.sign(createdAt, KIND, tags, content, onReady)
|
signer.sign(createdAt, KIND, tags, content, onReady)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun create(
|
fun build(
|
||||||
reportedUser: String,
|
reportedPost: Event,
|
||||||
type: ReportType,
|
type: ReportType,
|
||||||
signer: NostrSigner,
|
|
||||||
createdAt: Long = TimeUtils.now(),
|
createdAt: Long = TimeUtils.now(),
|
||||||
onReady: (ReportEvent) -> Unit,
|
) = eventTemplate(KIND, "", createdAt) {
|
||||||
) {
|
alt(ALT_PREFIX + type.code)
|
||||||
val content = ""
|
event(reportedPost.id, type)
|
||||||
|
user(reportedPost.pubKey, type)
|
||||||
|
|
||||||
val reportAuthorTag = arrayOf("p", reportedUser, type.name.lowercase())
|
if (reportedPost is AddressableEvent) {
|
||||||
val alt = AltTag.assemble("Report for ${type.name}")
|
address(reportedPost.address(), type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val tags: Array<Array<String>> = arrayOf(reportAuthorTag, alt)
|
fun build(
|
||||||
signer.sign(createdAt, KIND, tags, content, onReady)
|
reportedUser: HexKey,
|
||||||
|
type: ReportType,
|
||||||
|
createdAt: Long = TimeUtils.now(),
|
||||||
|
) = eventTemplate(KIND, "", createdAt) {
|
||||||
|
alt(ALT_PREFIX + type.code)
|
||||||
|
user(reportedUser, type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ReportType {
|
|
||||||
EXPLICIT, // Not used anymore.
|
|
||||||
ILLEGAL,
|
|
||||||
SPAM,
|
|
||||||
IMPERSONATION,
|
|
||||||
NUDITY,
|
|
||||||
PROFANITY,
|
|
||||||
MALWARE,
|
|
||||||
MOD,
|
|
||||||
OTHER,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
|
||||||
|
enum class ReportType(
|
||||||
|
val code: String,
|
||||||
|
) {
|
||||||
|
EXPLICIT("explicit"), // Not used anymore.
|
||||||
|
ILLEGAL("illegal"),
|
||||||
|
SPAM("spam"),
|
||||||
|
IMPERSONATION("impersonation"),
|
||||||
|
NUDITY("nudity"),
|
||||||
|
PROFANITY("profanity"),
|
||||||
|
MALWARE("malware"),
|
||||||
|
MOD("mod"),
|
||||||
|
OTHER("other"),
|
||||||
|
;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun parseOrNull(
|
||||||
|
code: String,
|
||||||
|
tag: Array<String>,
|
||||||
|
): ReportType? =
|
||||||
|
when (code) {
|
||||||
|
EXPLICIT.code -> EXPLICIT
|
||||||
|
ILLEGAL.code -> ILLEGAL
|
||||||
|
SPAM.code -> SPAM
|
||||||
|
IMPERSONATION.code -> IMPERSONATION
|
||||||
|
NUDITY.code -> NUDITY
|
||||||
|
PROFANITY.code -> PROFANITY
|
||||||
|
MALWARE.code -> MALWARE
|
||||||
|
MOD.code -> MOD
|
||||||
|
"MOD" -> MOD
|
||||||
|
OTHER.code -> OTHER
|
||||||
|
else -> {
|
||||||
|
Log.w("ReportedEventTag", "Report type not supported: $code ${tag.joinToString(", ")}")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.HashSha256Tag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAddressTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedAuthorTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ReportedEventTag
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.tags.ServerTag
|
||||||
|
|
||||||
|
fun TagArrayBuilder<ReportEvent>.event(
|
||||||
|
eventId: HexKey,
|
||||||
|
reportType: ReportType,
|
||||||
|
) = addUnique(ReportedEventTag.assemble(eventId, reportType))
|
||||||
|
|
||||||
|
fun TagArrayBuilder<ReportEvent>.address(
|
||||||
|
address: Address,
|
||||||
|
reportType: ReportType,
|
||||||
|
) = addUnique(ReportedAddressTag.assemble(address, reportType))
|
||||||
|
|
||||||
|
fun TagArrayBuilder<ReportEvent>.user(
|
||||||
|
pubkey: HexKey,
|
||||||
|
reportType: ReportType,
|
||||||
|
) = addUnique(ReportedAuthorTag.assemble(pubkey, reportType))
|
||||||
|
|
||||||
|
fun TagArrayBuilder<ReportEvent>.hash(
|
||||||
|
x: String,
|
||||||
|
reportType: ReportType,
|
||||||
|
) = addUnique(HashSha256Tag.assemble(x, reportType))
|
||||||
|
|
||||||
|
fun TagArrayBuilder<ReportEvent>.server(url: String) = addUnique(ServerTag.assemble(url))
|
@ -18,10 +18,10 @@
|
|||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
* 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.
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
package com.vitorpamplona.quartz.nip70ProtectedEvts
|
package com.vitorpamplona.quartz.nip56Reports.tags
|
||||||
|
|
||||||
class ProtectedTagSerializer {
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
companion object {
|
|
||||||
fun toTagArray(reason: String = "") = arrayOf("-", reason)
|
interface BaseReportTag {
|
||||||
}
|
val type: ReportType?
|
||||||
}
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class DefaultReportTag {
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "report"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(tag: Array<String>): ReportType? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
ensure(tag[1].isNotEmpty()) { return null }
|
||||||
|
|
||||||
|
return ReportType.parseOrNull(tag[1], tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(type: ReportType? = null) = arrayOfNotNull(TAG_NAME, type?.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
class HashSha256Tag(
|
||||||
|
val hash: HexKey,
|
||||||
|
override val type: ReportType? = null,
|
||||||
|
) : BaseReportTag {
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "x"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(
|
||||||
|
tag: Array<String>,
|
||||||
|
defaultReportType: ReportType? = null,
|
||||||
|
): HashSha256Tag? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
ensure(tag[1].length == 64) { return null }
|
||||||
|
|
||||||
|
val type = tag.getOrNull(2)?.let { ReportType.parseOrNull(it, tag) } ?: defaultReportType
|
||||||
|
return HashSha256Tag(tag[1], type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(
|
||||||
|
hash: String,
|
||||||
|
type: ReportType? = null,
|
||||||
|
) = arrayOfNotNull(TAG_NAME, hash, type?.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.tags.addressables.Address
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class ReportedAddressTag(
|
||||||
|
val address: Address,
|
||||||
|
override val type: ReportType? = null,
|
||||||
|
) : BaseReportTag {
|
||||||
|
fun toTagArray() = assemble(address, type)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "a"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(
|
||||||
|
tag: Array<String>,
|
||||||
|
defaultReportType: ReportType? = null,
|
||||||
|
): ReportedAddressTag? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
ensure(tag[1].isNotEmpty()) { return null }
|
||||||
|
|
||||||
|
val address = Address.parse(tag[1])
|
||||||
|
|
||||||
|
ensure(address != null) { return null }
|
||||||
|
|
||||||
|
val type =
|
||||||
|
if (tag.size == 2) {
|
||||||
|
defaultReportType
|
||||||
|
} else if (tag.size == 3) {
|
||||||
|
ReportType.parseOrNull(tag[2], tag) ?: defaultReportType
|
||||||
|
} else {
|
||||||
|
ReportType.parseOrNull(tag[3], tag) ?: defaultReportType
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReportedAddressTag(address, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(
|
||||||
|
address: Address,
|
||||||
|
type: ReportType? = null,
|
||||||
|
) = arrayOfNotNull(TAG_NAME, address.toValue(), type?.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class ReportedAuthorTag(
|
||||||
|
val pubkey: HexKey,
|
||||||
|
override val type: ReportType? = null,
|
||||||
|
) : BaseReportTag {
|
||||||
|
fun toTagArray() = assemble(pubkey, type)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "p"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(
|
||||||
|
tag: Array<String>,
|
||||||
|
defaultReportType: ReportType? = null,
|
||||||
|
): ReportedAuthorTag? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
ensure(tag[1].length == 64) { return null }
|
||||||
|
|
||||||
|
val type =
|
||||||
|
if (tag.size == 2) {
|
||||||
|
defaultReportType
|
||||||
|
} else if (tag.size == 3) {
|
||||||
|
ReportType.parseOrNull(tag[2], tag) ?: defaultReportType
|
||||||
|
} else {
|
||||||
|
ReportType.parseOrNull(tag[3], tag) ?: defaultReportType
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReportedAuthorTag(tag[1], type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(
|
||||||
|
pubkey: HexKey,
|
||||||
|
type: ReportType? = null,
|
||||||
|
) = arrayOfNotNull(TAG_NAME, pubkey, type?.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Immutable
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.nip56Reports.ReportType
|
||||||
|
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
@Immutable
|
||||||
|
class ReportedEventTag(
|
||||||
|
val eventId: HexKey,
|
||||||
|
override val type: ReportType? = null,
|
||||||
|
) : BaseReportTag {
|
||||||
|
fun toTagArray() = assemble(eventId, type)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "e"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(
|
||||||
|
tag: Array<String>,
|
||||||
|
defaultReportType: ReportType? = null,
|
||||||
|
): ReportedEventTag? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
ensure(tag[1].length == 64) { return null }
|
||||||
|
|
||||||
|
val type =
|
||||||
|
if (tag.size == 2) {
|
||||||
|
defaultReportType
|
||||||
|
} else if (tag.size == 3) {
|
||||||
|
ReportType.parseOrNull(tag[2], tag) ?: defaultReportType
|
||||||
|
} else {
|
||||||
|
ReportType.parseOrNull(tag[3], tag) ?: defaultReportType
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReportedEventTag(tag[1], type)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(
|
||||||
|
eventId: HexKey,
|
||||||
|
type: ReportType? = null,
|
||||||
|
) = arrayOfNotNull(TAG_NAME, eventId, type?.code)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 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.quartz.nip56Reports.tags
|
||||||
|
|
||||||
|
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||||
|
import com.vitorpamplona.quartz.utils.ensure
|
||||||
|
|
||||||
|
class ServerTag {
|
||||||
|
companion object {
|
||||||
|
const val TAG_NAME = "server"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun parse(tag: Array<String>): String? {
|
||||||
|
ensure(tag.has(1)) { return null }
|
||||||
|
ensure(tag[0] == TAG_NAME) { return null }
|
||||||
|
return tag[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(url: String) = arrayOf(TAG_NAME, url)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun assemble(urls: List<String>) = urls.map { assemble(it) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user