Initial support for separate vertical and horizontal videos.

This commit is contained in:
Vitor Pamplona 2023-12-26 18:02:13 -05:00
parent 1cedc8a6c8
commit 4afb0027fb
4 changed files with 285 additions and 0 deletions

View File

@ -0,0 +1,99 @@
package com.vitorpamplona.quartz.events
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.signers.NostrSigner
@Immutable
abstract class VideoEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
kind: Int,
tags: Array<Array<String>>,
content: String,
sig: HexKey
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
fun url() = tags.firstOrNull { it.size > 1 && it[0] == URL }?.get(1)
fun urls() = tags.filter { it.size > 1 && it[0] == URL }.map { it[1] }
fun mimeType() = tags.firstOrNull { it.size > 1 && it[0] == MIME_TYPE }?.get(1)
fun hash() = tags.firstOrNull { it.size > 1 && it[0] == HASH }?.get(1)
fun size() = tags.firstOrNull { it.size > 1 && it[0] == FILE_SIZE }?.get(1)
fun alt() = tags.firstOrNull { it.size > 1 && it[0] == ALT }?.get(1)
fun dimensions() = tags.firstOrNull { it.size > 1 && it[0] == DIMENSION }?.get(1)
fun magnetURI() = tags.firstOrNull { it.size > 1 && it[0] == MAGNET_URI }?.get(1)
fun torrentInfoHash() = tags.firstOrNull { it.size > 1 && it[0] == TORRENT_INFOHASH }?.get(1)
fun blurhash() = tags.firstOrNull { it.size > 1 && it[0] == BLUR_HASH }?.get(1)
fun hasUrl() = tags.any { it.size > 1 && it[0] == URL }
companion object {
private const val URL = "url"
private const val ENCRYPTION_KEY = "aes-256-gcm"
private const val MIME_TYPE = "m"
private const val FILE_SIZE = "size"
private const val DIMENSION = "dim"
private const val HASH = "x"
private const val MAGNET_URI = "magnet"
private const val TORRENT_INFOHASH = "i"
private const val BLUR_HASH = "blurhash"
private const val ORIGINAL_HASH = "ox"
private const val ALT = "alt"
private const val TITLE = "title"
private const val PUBLISHED_AT = "published_at"
private const val SUMMARY = "summary"
private const val DURATION = "duration"
private const val IMAGE = "image"
private const val THUMB = "thumb"
fun create(
kind: Int,
url: String,
magnetUri: String? = null,
mimeType: String? = null,
alt: String? = null,
hash: String? = null,
size: String? = null,
dimensions: String? = null,
blurhash: String? = null,
originalHash: String? = null,
magnetURI: String? = null,
torrentInfoHash: String? = null,
encryptionKey: AESGCM? = null,
sensitiveContent: Boolean? = null,
altDescription: String,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (FileHeaderEvent) -> Unit
) {
val tags = listOfNotNull(
arrayOf(URL, url),
magnetUri?.let { arrayOf(MAGNET_URI, it) },
mimeType?.let { arrayOf(MIME_TYPE, it) },
alt?.ifBlank { null }?.let { arrayOf(ALT, it) } ?: arrayOf("alt", altDescription),
hash?.let { arrayOf(HASH, it) },
size?.let { arrayOf(FILE_SIZE, it) },
dimensions?.let { arrayOf(DIMENSION, it) },
blurhash?.let { arrayOf(BLUR_HASH, it) },
originalHash?.let { arrayOf(ORIGINAL_HASH, it) },
magnetURI?.let { arrayOf(MAGNET_URI, it) },
torrentInfoHash?.let { arrayOf(TORRENT_INFOHASH, it) },
encryptionKey?.let { arrayOf(ENCRYPTION_KEY, it.key, it.nonce) },
sensitiveContent?.let {
if (it) {
arrayOf("content-warning", "")
} else {
null
}
}
)
val content = alt ?: ""
signer.sign(createdAt, kind, tags.toTypedArray(), content, onReady)
}
}
}

View File

@ -0,0 +1,62 @@
package com.vitorpamplona.quartz.events
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.signers.NostrSigner
@Immutable
class VideoHorizontalEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
tags: Array<Array<String>>,
content: String,
sig: HexKey
) : VideoEvent(id, pubKey, createdAt, kind, tags, content, sig) {
companion object {
const val kind = 34235
const val altDescription = "Horizontal Video"
fun create(
url: String,
magnetUri: String? = null,
mimeType: String? = null,
alt: String? = null,
hash: String? = null,
size: String? = null,
dimensions: String? = null,
blurhash: String? = null,
originalHash: String? = null,
magnetURI: String? = null,
torrentInfoHash: String? = null,
encryptionKey: AESGCM? = null,
sensitiveContent: Boolean? = null,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (FileHeaderEvent) -> Unit
) {
create(
kind,
url,
magnetUri,
mimeType,
alt,
hash,
size,
dimensions,
blurhash,
originalHash,
magnetURI,
torrentInfoHash,
encryptionKey,
sensitiveContent,
altDescription,
signer,
createdAt,
onReady
)
}
}
}

View File

@ -0,0 +1,61 @@
package com.vitorpamplona.quartz.events
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.signers.NostrSigner
@Immutable
class VideoVerticalEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
tags: Array<Array<String>>,
content: String,
sig: HexKey
) : VideoEvent(id, pubKey, createdAt, kind, tags, content, sig) {
companion object {
const val kind = 34236
const val altDescription = "Vertical Video"
fun create(
url: String,
magnetUri: String? = null,
mimeType: String? = null,
alt: String? = null,
hash: String? = null,
size: String? = null,
dimensions: String? = null,
blurhash: String? = null,
originalHash: String? = null,
magnetURI: String? = null,
torrentInfoHash: String? = null,
encryptionKey: AESGCM? = null,
sensitiveContent: Boolean? = null,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (FileHeaderEvent) -> Unit
) {
create(
kind,
url,
magnetUri,
mimeType,
alt,
hash,
size,
dimensions,
blurhash,
originalHash,
magnetURI,
torrentInfoHash,
encryptionKey,
sensitiveContent,
altDescription,
signer,
createdAt,
onReady
)
}
}
}

View File

@ -0,0 +1,63 @@
package com.vitorpamplona.quartz.events
import androidx.compose.runtime.Immutable
import com.vitorpamplona.quartz.utils.TimeUtils
import com.vitorpamplona.quartz.encoders.toHexKey
import com.vitorpamplona.quartz.crypto.CryptoUtils
import com.vitorpamplona.quartz.crypto.KeyPair
import com.vitorpamplona.quartz.encoders.ATag
import com.vitorpamplona.quartz.encoders.HexKey
import com.vitorpamplona.quartz.signers.NostrSigner
@Immutable
class VideoViewEvent(
id: HexKey,
pubKey: HexKey,
createdAt: Long,
tags: Array<Array<String>>,
content: String,
sig: HexKey
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig) {
companion object {
const val kind = 34237
fun create(
video: ATag,
signer: NostrSigner,
viewStart: Long?,
viewEnd: Long?,
createdAt: Long = TimeUtils.now(),
onReady: (VideoViewEvent) -> Unit
) {
val tags = mutableListOf<Array<String>>()
val aTag = video.toTag()
tags.add(arrayOf("d", aTag))
tags.add(arrayOf("a", aTag))
if (viewEnd != null)
tags.add(arrayOf("viewed", viewStart?.toString() ?: "0", viewEnd.toString()))
else
tags.add(arrayOf("viewed", viewStart?.toString() ?: "0"))
signer.sign(createdAt, kind, tags.toTypedArray(), "", onReady)
}
fun addViewedTime(
event: VideoViewEvent,
viewStart: Long?,
viewEnd: Long?,
signer: NostrSigner,
createdAt: Long = TimeUtils.now(),
onReady: (VideoViewEvent) -> Unit
) {
val tags = event.tags.toMutableList()
if (viewEnd != null)
tags.add(arrayOf("viewed", viewStart?.toString() ?: "0", viewEnd.toString()))
else
tags.add(arrayOf("viewed", viewStart?.toString() ?: "0"))
signer.sign(createdAt, kind, tags.toTypedArray(), "", onReady)
}
}
}