Adds support to reply to Yaks with another voice message.
This commit is contained in:
@@ -26,6 +26,7 @@ import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.WaveformTag
|
||||
|
||||
data class AudioMeta(
|
||||
val url: String,
|
||||
val mimeType: String? = null,
|
||||
val hash: String? = null,
|
||||
val duration: Int? = null,
|
||||
val waveform: List<Int>? = null,
|
||||
@@ -33,6 +34,7 @@ data class AudioMeta(
|
||||
fun toIMetaArray(): Array<String> =
|
||||
IMetaTagBuilder(url)
|
||||
.apply {
|
||||
mimeType?.let { mimeType(it) }
|
||||
hash?.let { hash(it) }
|
||||
duration?.let { duration(it) }
|
||||
waveform?.let { waveform(it) }
|
||||
@@ -42,10 +44,11 @@ data class AudioMeta(
|
||||
companion object {
|
||||
fun parse(iMeta: IMetaTag): AudioMeta =
|
||||
AudioMeta(
|
||||
iMeta.url,
|
||||
iMeta.hash()?.firstOrNull(),
|
||||
iMeta.duration()?.firstOrNull()?.toIntOrNull(),
|
||||
iMeta.waveform()?.firstOrNull()?.let { WaveformTag.parseWave(it) },
|
||||
url = iMeta.url,
|
||||
mimeType = iMeta.mimeType()?.firstOrNull(),
|
||||
hash = iMeta.hash()?.firstOrNull(),
|
||||
duration = iMeta.duration()?.firstOrNull()?.toIntOrNull(),
|
||||
waveform = iMeta.waveform()?.firstOrNull()?.let { WaveformTag.parseWave(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ open class BaseVoiceEvent(
|
||||
initializer: TagArrayBuilder<T>.() -> Unit = {},
|
||||
) = eventTemplate(kind, voiceMessage.url, createdAt) {
|
||||
alt(alt)
|
||||
audioIMeta(voiceMessage)
|
||||
initializer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTagBuilder
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.DurationTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.MimeTypeTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.WaveformTag
|
||||
|
||||
/**
|
||||
@@ -34,3 +35,5 @@ fun IMetaTagBuilder.hash(hash: HexKey) = add(HashSha256Tag.TAG_NAME, hash)
|
||||
fun IMetaTagBuilder.duration(size: Int) = add(DurationTag.TAG_NAME, size.toString())
|
||||
|
||||
fun IMetaTagBuilder.waveform(wave: List<Int>) = add(WaveformTag.TAG_NAME, WaveformTag.assembleWave(wave))
|
||||
|
||||
fun IMetaTagBuilder.mimeType(mime: String) = add(MimeTypeTag.TAG_NAME, mime)
|
||||
|
||||
@@ -23,6 +23,7 @@ package com.vitorpamplona.quartz.nipA0VoiceMessages
|
||||
import com.vitorpamplona.quartz.nip92IMeta.IMetaTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.DurationTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.MimeTypeTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.WaveformTag
|
||||
|
||||
fun IMetaTag.hash() = properties.get(HashSha256Tag.TAG_NAME)
|
||||
@@ -30,3 +31,5 @@ fun IMetaTag.hash() = properties.get(HashSha256Tag.TAG_NAME)
|
||||
fun IMetaTag.duration() = properties.get(DurationTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.waveform() = properties.get(WaveformTag.TAG_NAME)
|
||||
|
||||
fun IMetaTag.mimeType() = properties.get(MimeTypeTag.TAG_NAME)
|
||||
|
||||
+22
-1
@@ -20,15 +20,21 @@
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipA0VoiceMessages
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip94FileMetadata.tags.HashSha256Tag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyAuthorTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyEventTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyKindTag
|
||||
|
||||
fun <T : BaseVoiceEvent> TagArrayBuilder<T>.audioIMeta(
|
||||
url: String,
|
||||
mimeType: String? = null,
|
||||
hash: String? = null,
|
||||
duration: Int? = null,
|
||||
waveform: List<Int>? = null,
|
||||
) = audioIMeta(AudioMeta(url, hash, duration, waveform))
|
||||
) = audioIMeta(AudioMeta(url, mimeType, hash, duration, waveform))
|
||||
|
||||
fun <T : BaseVoiceEvent> TagArrayBuilder<T>.audioIMeta(imeta: AudioMeta): TagArrayBuilder<T> {
|
||||
add(imeta.toIMetaArray())
|
||||
@@ -40,3 +46,18 @@ fun <T : BaseVoiceEvent> TagArrayBuilder<T>.audioIMeta(audioUrls: List<AudioMeta
|
||||
audioUrls.forEach { audioIMeta(it) }
|
||||
return this
|
||||
}
|
||||
|
||||
fun TagArrayBuilder<VoiceReplyEvent>.replyEvent(
|
||||
eventId: String,
|
||||
relayHint: NormalizedRelayUrl?,
|
||||
pubkey: String?,
|
||||
) = addUnique(ReplyEventTag.assemble(eventId, relayHint, pubkey))
|
||||
|
||||
fun TagArrayBuilder<VoiceReplyEvent>.replyKind(kind: String) = addUnique(ReplyKindTag.assemble(kind))
|
||||
|
||||
fun TagArrayBuilder<VoiceReplyEvent>.replyKind(kind: Int) = addUnique(ReplyKindTag.assemble(kind))
|
||||
|
||||
fun TagArrayBuilder<VoiceReplyEvent>.replyAuthor(
|
||||
pubKey: HexKey,
|
||||
relay: NormalizedRelayUrl?,
|
||||
) = add(ReplyAuthorTag.assemble(pubKey, relay))
|
||||
|
||||
@@ -38,6 +38,14 @@ class VoiceEvent(
|
||||
const val KIND = 1222
|
||||
const val ALT_DESCRIPTION = "Voice message"
|
||||
|
||||
fun build(
|
||||
url: String,
|
||||
mimeType: String?,
|
||||
hash: String,
|
||||
duration: Int,
|
||||
waveform: List<Int>,
|
||||
) = build(AudioMeta(url, mimeType, hash, duration, waveform))
|
||||
|
||||
fun build(
|
||||
voiceMessage: AudioMeta,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
|
||||
+37
-1
@@ -23,7 +23,12 @@ package com.vitorpamplona.quartz.nipA0VoiceMessages
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyAuthorTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyEventTag
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.tags.ReplyKindTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.lastNotNullOfOrNull
|
||||
|
||||
@Immutable
|
||||
class VoiceReplyEvent(
|
||||
@@ -34,14 +39,45 @@ class VoiceReplyEvent(
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : BaseVoiceEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
fun replyAuthor() = tags.firstNotNullOfOrNull(ReplyAuthorTag::parse)
|
||||
|
||||
fun replyAuthors() = tags.filter(ReplyAuthorTag::match)
|
||||
|
||||
fun replyAuthorKeys() = tags.mapNotNull(ReplyAuthorTag::parseKey)
|
||||
|
||||
fun replyAuthorHints() = tags.mapNotNull(ReplyAuthorTag::parseAsHint)
|
||||
|
||||
fun directReplies() = tags.filter { ReplyEventTag.match(it) }
|
||||
|
||||
fun directKinds() = tags.filter(ReplyKindTag::match)
|
||||
|
||||
fun markedReplyTos(): List<HexKey> = tags.mapNotNull(ReplyEventTag::parseKey)
|
||||
|
||||
fun replyingTo(): HexKey? = tags.lastNotNullOfOrNull(ReplyEventTag::parseKey)
|
||||
|
||||
companion object {
|
||||
const val KIND = 1244
|
||||
const val ALT_DESCRIPTION = "Voice reply"
|
||||
|
||||
fun build(
|
||||
url: String,
|
||||
mimeType: String?,
|
||||
hash: String,
|
||||
duration: Int,
|
||||
waveform: List<Int>,
|
||||
replyingTo: EventHintBundle<VoiceEvent>,
|
||||
) = build(AudioMeta(url, mimeType, hash, duration, waveform), replyingTo)
|
||||
|
||||
fun build(
|
||||
voiceMessage: AudioMeta,
|
||||
replyingTo: EventHintBundle<VoiceEvent>,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
initializer: TagArrayBuilder<VoiceReplyEvent>.() -> Unit = {},
|
||||
) = build(voiceMessage, KIND, ALT_DESCRIPTION, createdAt, initializer)
|
||||
) = build(voiceMessage, KIND, ALT_DESCRIPTION, createdAt) {
|
||||
replyEvent(replyingTo.event.id, replyingTo.relay, replyingTo.event.pubKey)
|
||||
replyKind(replyingTo.event.kind)
|
||||
replyAuthor(replyingTo.event.pubKey, replyingTo.authorHomeRelay)
|
||||
initializer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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.quartz.nipA0VoiceMessages.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
class MimeTypeTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "m"
|
||||
|
||||
fun isIn(
|
||||
tag: Array<String>,
|
||||
mimeTypes: Set<String>,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] in mimeTypes
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): String? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].isNotEmpty()) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(mimeType: String) = arrayOf(TAG_NAME, mimeType)
|
||||
}
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* 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.quartz.nipA0VoiceMessages.tags
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.PubKeyHint
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PubKeyReferenceTag
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
@Immutable
|
||||
data class ReplyAuthorTag(
|
||||
override val pubKey: HexKey,
|
||||
override val relayHint: NormalizedRelayUrl? = null,
|
||||
) : PubKeyReferenceTag {
|
||||
fun toTagArray() = assemble(pubKey, relayHint)
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "p"
|
||||
|
||||
@JvmStatic
|
||||
fun match(tag: Tag) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Tag): ReplyAuthorTag? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
|
||||
val hint = tag.getOrNull(2)?.let { RelayUrlNormalizer.normalizeOrNull(it) }
|
||||
|
||||
return ReplyAuthorTag(tag[1], hint)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Tag): HexKey? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): PubKeyHint? {
|
||||
ensure(tag.has(2)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
ensure(tag[2].isNotEmpty()) { return null }
|
||||
|
||||
val hint = RelayUrlNormalizer.normalizeOrNull(tag[2])
|
||||
ensure(hint != null) { return null }
|
||||
|
||||
return PubKeyHint(tag[1], hint)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
pubkey: HexKey,
|
||||
relayHint: NormalizedRelayUrl?,
|
||||
) = arrayOfNotNull(TAG_NAME, pubkey, relayHint?.url)
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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.quartz.nipA0VoiceMessages.tags
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.types.EventIdHint
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.RelayUrlNormalizer
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.EventReference
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.arrayOfNotNull
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
@Immutable
|
||||
class ReplyEventTag(
|
||||
val ref: EventReference,
|
||||
) {
|
||||
constructor(eventId: String, relayHint: NormalizedRelayUrl?, pubkey: String?) : this(EventReference(eventId, pubkey, relayHint))
|
||||
|
||||
fun toTagArray() = assemble(ref)
|
||||
|
||||
companion object {
|
||||
const val TAG_NAME = "e"
|
||||
|
||||
@JvmStatic
|
||||
fun match(tag: Tag) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
|
||||
|
||||
@JvmStatic
|
||||
fun isTagged(
|
||||
tag: Array<String>,
|
||||
eventId: String,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] == eventId
|
||||
|
||||
@JvmStatic
|
||||
fun isIn(
|
||||
tag: Array<String>,
|
||||
eventIds: Set<String>,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] in eventIds
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Array<String>): ReplyEventTag? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
return ReplyEventTag(tag[1], tag.getOrNull(2)?.let { RelayUrlNormalizer.normalizeOrNull(it) }, tag.getOrNull(3))
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseKey(tag: Array<String>): String? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseValidKey(tag: Array<String>): String? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
ensure(Hex.isHex(tag[1])) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun parseAsHint(tag: Array<String>): EventIdHint? {
|
||||
ensure(tag.has(2)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].length == 64) { return null }
|
||||
ensure(tag[2].isNotEmpty()) { return null }
|
||||
|
||||
val relayHint = RelayUrlNormalizer.normalizeOrNull(tag[2])
|
||||
ensure(relayHint != null) { return null }
|
||||
|
||||
return EventIdHint(tag[1], relayHint)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(
|
||||
eventId: HexKey,
|
||||
relay: NormalizedRelayUrl?,
|
||||
pubkey: String?,
|
||||
) = arrayOfNotNull(TAG_NAME, eventId, relay?.url, pubkey)
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(ref: EventReference) = assemble(ref.eventId, ref.relayHint, ref.author)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 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.quartz.nipA0VoiceMessages.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Tag
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nip73ExternalIds.ExternalId
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
class ReplyKindTag {
|
||||
companion object {
|
||||
const val TAG_NAME = "k"
|
||||
|
||||
@JvmStatic
|
||||
fun match(tag: Tag) = tag.has(1) && tag[0] == TAG_NAME && tag[1].isNotEmpty()
|
||||
|
||||
@JvmStatic
|
||||
fun isKind(
|
||||
tag: Tag,
|
||||
kind: String,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] == kind
|
||||
|
||||
@JvmStatic
|
||||
fun isTagged(
|
||||
tag: Tag,
|
||||
kind: String,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] == kind
|
||||
|
||||
@JvmStatic
|
||||
fun isIn(
|
||||
tag: Tag,
|
||||
kinds: Set<String>,
|
||||
) = tag.has(1) && tag[0] == TAG_NAME && tag[1] in kinds
|
||||
|
||||
@JvmStatic
|
||||
fun parse(tag: Tag): String? {
|
||||
ensure(tag.has(1)) { return null }
|
||||
ensure(tag[0] == TAG_NAME) { return null }
|
||||
ensure(tag[1].isNotEmpty()) { return null }
|
||||
return tag[1]
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(kind: String) = arrayOf(TAG_NAME, kind)
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(kind: Int) = arrayOf(TAG_NAME, kind.toString())
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(id: ExternalId) = assemble(id.toKind())
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(kinds: List<String>): List<Tag> = kinds.map { assemble(it) }
|
||||
|
||||
@JvmStatic
|
||||
fun assemble(kinds: Set<String>): List<Tag> = kinds.map { assemble(it) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user