mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-03-17 21:31:57 +01:00
- Migrates Video events to imeta tags
- Removes youtu.be links from the video feed. - Checks for video file types in uppercase as well as lowercase
This commit is contained in:
parent
81591d6f76
commit
b47d9ad4d9
@ -1976,14 +1976,12 @@ class Account(
|
||||
if (headerInfo.dim.height > headerInfo.dim.width) {
|
||||
VideoVerticalEvent.create(
|
||||
url = url,
|
||||
magnetUri = magnetUri,
|
||||
mimeType = headerInfo.mimeType,
|
||||
hash = headerInfo.hash,
|
||||
size = headerInfo.size.toString(),
|
||||
size = headerInfo.size,
|
||||
dimensions = headerInfo.dim,
|
||||
blurhash = headerInfo.blurHash,
|
||||
alt = alt,
|
||||
originalHash = originalHash,
|
||||
sensitiveContent = sensitiveContent,
|
||||
signer = signer,
|
||||
) { event ->
|
||||
@ -1992,14 +1990,12 @@ class Account(
|
||||
} else {
|
||||
VideoHorizontalEvent.create(
|
||||
url = url,
|
||||
magnetUri = magnetUri,
|
||||
mimeType = headerInfo.mimeType,
|
||||
hash = headerInfo.hash,
|
||||
size = headerInfo.size.toString(),
|
||||
size = headerInfo.size,
|
||||
dimensions = headerInfo.dim,
|
||||
blurhash = headerInfo.blurHash,
|
||||
alt = alt,
|
||||
originalHash = originalHash,
|
||||
sensitiveContent = sensitiveContent,
|
||||
signer = signer,
|
||||
) { event ->
|
||||
|
@ -33,6 +33,7 @@ import com.vitorpamplona.quartz.events.MuteListEvent
|
||||
import com.vitorpamplona.quartz.events.PeopleListEvent
|
||||
import com.vitorpamplona.quartz.events.PictureEvent
|
||||
import com.vitorpamplona.quartz.events.VideoHorizontalEvent
|
||||
import com.vitorpamplona.quartz.events.VideoMeta
|
||||
import com.vitorpamplona.quartz.events.VideoVerticalEvent
|
||||
|
||||
class VideoFeedFilter(
|
||||
@ -66,6 +67,29 @@ class VideoFeedFilter(
|
||||
return collection.filterTo(HashSet()) { acceptableEvent(it, params) }
|
||||
}
|
||||
|
||||
fun acceptableUrls(
|
||||
baseUrls: List<String>,
|
||||
mimeType: String?,
|
||||
): Boolean {
|
||||
// we don't have an youtube player
|
||||
val urls = baseUrls.filter { !it.contains("youtu.be") }
|
||||
|
||||
val isSupportedMimeType = mimeType?.let { SUPPORTED_VIDEO_FEED_MIME_TYPES_SET.contains(it) } ?: false
|
||||
|
||||
return urls.isNotEmpty() && (urls.any { isImageOrVideoUrl(it) } || isSupportedMimeType)
|
||||
}
|
||||
|
||||
fun acceptableiMetas(iMetas: List<VideoMeta>): Boolean =
|
||||
iMetas.any {
|
||||
!it.url.contains("youtu.be") && (isImageOrVideoUrl(it.url) || (it.mimeType == null || SUPPORTED_VIDEO_FEED_MIME_TYPES_SET.contains(it.mimeType)))
|
||||
}
|
||||
|
||||
fun acceptanceEvent(noteEvent: FileHeaderEvent) = acceptableUrls(noteEvent.urls(), noteEvent.mimeType())
|
||||
|
||||
fun acceptanceEvent(noteEvent: VideoVerticalEvent) = acceptableiMetas(noteEvent.imetaTags())
|
||||
|
||||
fun acceptanceEvent(noteEvent: VideoHorizontalEvent) = acceptableiMetas(noteEvent.imetaTags())
|
||||
|
||||
fun acceptableEvent(
|
||||
note: Note,
|
||||
params: FilterByListParams,
|
||||
@ -77,9 +101,9 @@ class VideoFeedFilter(
|
||||
}
|
||||
|
||||
return (
|
||||
(noteEvent is FileHeaderEvent && noteEvent.hasUrl() && (noteEvent.urls().any { isImageOrVideoUrl(it) } || noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET))) ||
|
||||
(noteEvent is VideoVerticalEvent && noteEvent.hasUrl() && (noteEvent.urls().any { isImageOrVideoUrl(it) } || noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET))) ||
|
||||
(noteEvent is VideoHorizontalEvent && noteEvent.hasUrl() && (noteEvent.urls().any { isImageOrVideoUrl(it) } || noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET))) ||
|
||||
(noteEvent is FileHeaderEvent && acceptanceEvent(noteEvent)) ||
|
||||
(noteEvent is VideoVerticalEvent && acceptanceEvent(noteEvent)) ||
|
||||
(noteEvent is VideoHorizontalEvent && acceptanceEvent(noteEvent)) ||
|
||||
(noteEvent is FileStorageHeaderEvent && noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET)) ||
|
||||
noteEvent is PictureEvent
|
||||
) &&
|
||||
|
@ -71,45 +71,41 @@ fun VideoDisplay(
|
||||
nav: INav,
|
||||
) {
|
||||
val event = (note.event as? VideoEvent) ?: return
|
||||
val fullUrl = event.url() ?: return
|
||||
val imeta = event.imetaTags().firstOrNull() ?: return
|
||||
|
||||
val title = event.title()
|
||||
val summary = event.content.ifBlank { null }?.takeIf { title != it }
|
||||
val image = event.thumb() ?: event.image()
|
||||
val isYouTube = fullUrl.contains("youtube.com") || fullUrl.contains("youtu.be")
|
||||
val image = imeta.image.firstOrNull()
|
||||
val isYouTube = imeta.url.contains("youtube.com") || imeta.url.contains("youtu.be")
|
||||
val tags = remember(note) { note.event?.tags()?.toImmutableListOfLists() ?: EmptyTagList }
|
||||
|
||||
val content by
|
||||
remember(note) {
|
||||
val blurHash = event.blurhash()
|
||||
val hash = event.hash()
|
||||
val dimensions = event.dimensions()
|
||||
val description = event.content.ifBlank { null } ?: event.alt()
|
||||
val isImage = event.mimeType()?.startsWith("image/") == true || RichTextParser.isImageUrl(fullUrl)
|
||||
val isImage = imeta.mimeType?.startsWith("image/") == true || RichTextParser.isImageUrl(imeta.url)
|
||||
val uri = note.toNostrUri()
|
||||
val mimeType = event.mimeType()
|
||||
|
||||
mutableStateOf<BaseMediaContent>(
|
||||
if (isImage) {
|
||||
MediaUrlImage(
|
||||
url = fullUrl,
|
||||
url = imeta.url,
|
||||
description = description,
|
||||
hash = hash,
|
||||
blurhash = blurHash,
|
||||
dim = dimensions,
|
||||
hash = imeta.hash,
|
||||
blurhash = imeta.blurhash,
|
||||
dim = imeta.dimension,
|
||||
uri = uri,
|
||||
mimeType = mimeType,
|
||||
mimeType = imeta.mimeType,
|
||||
)
|
||||
} else {
|
||||
MediaUrlVideo(
|
||||
url = fullUrl,
|
||||
url = imeta.url,
|
||||
description = description,
|
||||
hash = hash,
|
||||
dim = dimensions,
|
||||
hash = imeta.hash,
|
||||
dim = imeta.dimension,
|
||||
uri = uri,
|
||||
authorName = note.author?.toBestDisplayName(),
|
||||
artworkUri = event.thumb() ?: event.image(),
|
||||
mimeType = mimeType,
|
||||
artworkUri = imeta.image.firstOrNull(),
|
||||
mimeType = imeta.mimeType,
|
||||
)
|
||||
},
|
||||
)
|
||||
@ -126,7 +122,7 @@ fun VideoDisplay(
|
||||
if (isYouTube) {
|
||||
val uri = LocalUriHandler.current
|
||||
Row(
|
||||
modifier = Modifier.clickable { runCatching { uri.openUri(fullUrl) } },
|
||||
modifier = Modifier.clickable { runCatching { uri.openUri(imeta.url) } },
|
||||
) {
|
||||
image?.let {
|
||||
AsyncImage(
|
||||
|
@ -42,39 +42,34 @@ fun JustVideoDisplay(
|
||||
accountViewModel: AccountViewModel,
|
||||
) {
|
||||
val event = (note.event as? VideoEvent) ?: return
|
||||
val fullUrl = event.url() ?: return
|
||||
val imeta = event.imetaTags().getOrNull(0) ?: return
|
||||
|
||||
val content by
|
||||
remember(note) {
|
||||
val blurHash = event.blurhash()
|
||||
val hash = event.hash()
|
||||
val dimensions = event.dimensions()
|
||||
val description = event.content.ifEmpty { null } ?: event.alt()
|
||||
val isImage = event.mimeType()?.startsWith("image/") == true || RichTextParser.isImageUrl(fullUrl)
|
||||
val uri = note.toNostrUri()
|
||||
val mimeType = event.mimeType()
|
||||
val description = event.content.ifEmpty { null } ?: imeta.alt ?: event.alt()
|
||||
val isImage = imeta.mimeType?.startsWith("image/") == true || RichTextParser.isImageUrl(imeta.url)
|
||||
|
||||
mutableStateOf<BaseMediaContent>(
|
||||
if (isImage) {
|
||||
MediaUrlImage(
|
||||
url = fullUrl,
|
||||
url = imeta.url,
|
||||
description = description,
|
||||
hash = hash,
|
||||
blurhash = blurHash,
|
||||
dim = dimensions,
|
||||
uri = uri,
|
||||
mimeType = mimeType,
|
||||
hash = imeta.hash,
|
||||
blurhash = imeta.blurhash,
|
||||
dim = imeta.dimension,
|
||||
uri = note.toNostrUri(),
|
||||
mimeType = imeta.mimeType,
|
||||
)
|
||||
} else {
|
||||
MediaUrlVideo(
|
||||
url = fullUrl,
|
||||
url = imeta.url,
|
||||
description = description,
|
||||
hash = hash,
|
||||
blurhash = blurHash,
|
||||
dim = dimensions,
|
||||
uri = uri,
|
||||
hash = imeta.hash,
|
||||
blurhash = imeta.blurhash,
|
||||
dim = imeta.dimension,
|
||||
uri = note.toNostrUri(),
|
||||
authorName = note.author?.toBestDisplayName(),
|
||||
mimeType = mimeType,
|
||||
mimeType = imeta.mimeType,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
@ -67,7 +67,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.regex.Pattern
|
||||
|
||||
val EMAIL_PATTERN = Pattern.compile(".+@.+\\.[a-z]+")
|
||||
val EMAIL_PATTERN: Pattern = Pattern.compile(".+@.+\\.[a-z]+")
|
||||
|
||||
@Stable
|
||||
class AccountStateViewModel : ViewModel() {
|
||||
|
@ -66,7 +66,7 @@ class RichTextParser {
|
||||
} else {
|
||||
val removedParamsFromUrl = removeQueryParamsForExtensionComparison(fullUrl)
|
||||
isImage = imageExtensions.any { removedParamsFromUrl.endsWith(it) }
|
||||
isVideo = imageExtensions.any { removedParamsFromUrl.endsWith(it) }
|
||||
isVideo = videoExtensions.any { removedParamsFromUrl.endsWith(it) }
|
||||
}
|
||||
|
||||
return if (isImage) {
|
||||
@ -344,8 +344,11 @@ class RichTextParser {
|
||||
"^((http|https)://)?([A-Za-z0-9-_]+(\\.[A-Za-z0-9-_]+)+)(:[0-9]+)?(/[^?#]*)?(\\?[^#]*)?(#.*)?"
|
||||
.toRegex(RegexOption.IGNORE_CASE)
|
||||
|
||||
val imageExtensions = listOf("png", "jpg", "gif", "bmp", "jpeg", "webp", "svg", "avif")
|
||||
val videoExtensions = listOf("mp4", "avi", "wmv", "mpg", "amv", "webm", "mov", "mp3", "m3u8")
|
||||
val imageExt = listOf("png", "jpg", "gif", "bmp", "jpeg", "webp", "svg", "avif")
|
||||
val videoExt = listOf("mp4", "avi", "wmv", "mpg", "amv", "webm", "mov", "mp3", "m3u8")
|
||||
|
||||
val imageExtensions = imageExt + imageExt.map { it.uppercase() }
|
||||
val videoExtensions = videoExt + videoExt.map { it.uppercase() }
|
||||
|
||||
val base64contentPattern = Pattern.compile("data:image/(${imageExtensions.joinToString(separator = "|") { it } });base64,([a-zA-Z0-9+/]+={0,2})")
|
||||
|
||||
|
@ -22,8 +22,10 @@ package com.vitorpamplona.quartz.events
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.Nip92MediaAttachments.Companion.IMETA
|
||||
import com.vitorpamplona.quartz.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import com.vitorpamplona.quartz.utils.filter
|
||||
|
||||
@Immutable
|
||||
abstract class VideoEvent(
|
||||
@ -36,52 +38,73 @@ abstract class VideoEvent(
|
||||
sig: HexKey,
|
||||
) : BaseAddressableEvent(id, pubKey, createdAt, kind, tags, content, sig),
|
||||
RootScope {
|
||||
fun url() = tags.firstOrNull { it.size > 1 && it[0] == URL }?.get(1)
|
||||
private 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] }
|
||||
private 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)
|
||||
private 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)
|
||||
private 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)
|
||||
private fun size() = tags.firstOrNull { it.size > 1 && it[0] == FILE_SIZE }?.get(1)
|
||||
|
||||
private fun dimensions() = tags.firstOrNull { it.size > 1 && it[0] == DIMENSION }?.get(1)?.let { Dimension.parse(it) }
|
||||
|
||||
private fun blurhash() = tags.firstOrNull { it.size > 1 && it[0] == BLUR_HASH }?.get(1)
|
||||
|
||||
private fun image() = tags.filter { it.size > 1 && it[0] == IMAGE }.map { it[1] }
|
||||
|
||||
private fun thumb() = tags.firstOrNull { it.size > 1 && it[0] == THUMB }?.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)?.let { Dimension.parse(it) }
|
||||
|
||||
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 title() = tags.firstOrNull { it.size > 1 && it[0] == TITLE }?.get(1)
|
||||
|
||||
fun summary() = tags.firstOrNull { it.size > 1 && it[0] == SUMMARY }?.get(1)
|
||||
|
||||
fun image() = tags.firstOrNull { it.size > 1 && it[0] == IMAGE }?.get(1)
|
||||
|
||||
fun thumb() = tags.firstOrNull { it.size > 1 && it[0] == THUMB }?.get(1)
|
||||
fun duration() = tags.firstOrNull { it.size > 1 && it[0] == DURATION }?.get(1)
|
||||
|
||||
fun hasUrl() = tags.any { it.size > 1 && it[0] == URL }
|
||||
|
||||
fun isOneOf(mimeTypes: Set<String>) = tags.any { it.size > 1 && it[0] == FileHeaderEvent.MIME_TYPE && mimeTypes.contains(it[1]) }
|
||||
|
||||
// hack to fix pablo's bug
|
||||
fun rootVideo() =
|
||||
url()?.let {
|
||||
VideoMeta(
|
||||
url = it,
|
||||
mimeType = mimeType(),
|
||||
blurhash = blurhash(),
|
||||
alt = alt(),
|
||||
hash = hash(),
|
||||
dimension = dimensions(),
|
||||
size = size()?.toIntOrNull(),
|
||||
service = null,
|
||||
fallback = emptyList(),
|
||||
image = image(),
|
||||
)
|
||||
}
|
||||
|
||||
fun imetaTags() =
|
||||
tags
|
||||
.map { tagArray ->
|
||||
if (tagArray.size > 1 && tagArray[0] == IMETA) {
|
||||
VideoMeta.parse(tagArray)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.plus(rootVideo())
|
||||
.filterNotNull()
|
||||
|
||||
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"
|
||||
@ -91,47 +114,129 @@ abstract class VideoEvent(
|
||||
kind: Int,
|
||||
dTag: String,
|
||||
url: String,
|
||||
magnetUri: String? = null,
|
||||
mimeType: String? = null,
|
||||
alt: String? = null,
|
||||
hash: String? = null,
|
||||
size: String? = null,
|
||||
size: Int? = null,
|
||||
duration: Int? = null,
|
||||
dimensions: Dimension? = null,
|
||||
blurhash: String? = null,
|
||||
originalHash: String? = null,
|
||||
magnetURI: String? = null,
|
||||
torrentInfoHash: String? = null,
|
||||
sensitiveContent: Boolean? = null,
|
||||
service: String? = null,
|
||||
altDescription: String,
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (T) -> Unit,
|
||||
) {
|
||||
val tags =
|
||||
listOfNotNull(
|
||||
arrayOf("d", dTag),
|
||||
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.toString()) },
|
||||
blurhash?.let { arrayOf(BLUR_HASH, it) },
|
||||
originalHash?.let { arrayOf(ORIGINAL_HASH, it) },
|
||||
magnetURI?.let { arrayOf(MAGNET_URI, it) },
|
||||
torrentInfoHash?.let { arrayOf(TORRENT_INFOHASH, it) },
|
||||
sensitiveContent?.let {
|
||||
if (it) {
|
||||
arrayOf("content-warning", "")
|
||||
} else {
|
||||
null
|
||||
}
|
||||
},
|
||||
val video =
|
||||
VideoMeta(
|
||||
url,
|
||||
mimeType,
|
||||
blurhash,
|
||||
dimensions,
|
||||
alt,
|
||||
hash,
|
||||
size,
|
||||
service,
|
||||
emptyList(),
|
||||
emptyList(),
|
||||
)
|
||||
|
||||
val tags = mutableListOf<Array<String>>()
|
||||
|
||||
tags.add(arrayOf("d", dTag))
|
||||
tags.add(arrayOf(ALT, altDescription))
|
||||
if (sensitiveContent == true) {
|
||||
tags.add(arrayOf("content-warning", ""))
|
||||
}
|
||||
duration?.let { tags.add(arrayOf(DURATION, "duration")) }
|
||||
|
||||
tags.add(video.toIMetaArray())
|
||||
|
||||
val content = alt ?: ""
|
||||
signer.sign<T>(createdAt, kind, tags.toTypedArray(), content, onReady)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class VideoMeta(
|
||||
val url: String,
|
||||
val mimeType: String?,
|
||||
val blurhash: String?,
|
||||
val dimension: Dimension?,
|
||||
val alt: String?,
|
||||
val hash: String?,
|
||||
val size: Int?,
|
||||
val service: String?,
|
||||
val fallback: List<String>,
|
||||
val image: List<String>,
|
||||
) {
|
||||
fun toIMetaArray(): Array<String> =
|
||||
(
|
||||
listOfNotNull(
|
||||
"imeta",
|
||||
"$URL $url",
|
||||
mimeType?.let { "$MIME_TYPE $it" },
|
||||
alt?.let { "$ALT $it" },
|
||||
hash?.let { "$HASH $it" },
|
||||
size?.let { "$FILE_SIZE $it" },
|
||||
dimension?.let { "$DIMENSION $it" },
|
||||
blurhash?.let { "$BLUR_HASH $it" },
|
||||
service?.let { "$SERVICE $it" },
|
||||
) +
|
||||
fallback.map { "$FALLBACK $it" } +
|
||||
image.map { "$IMAGE $it" }
|
||||
|
||||
).toTypedArray()
|
||||
|
||||
companion object {
|
||||
const val URL = "url"
|
||||
const val MIME_TYPE = "m"
|
||||
const val FILE_SIZE = "size"
|
||||
const val DIMENSION = "dim"
|
||||
const val HASH = "x"
|
||||
const val BLUR_HASH = "blurhash"
|
||||
const val ALT = "alt"
|
||||
const val FALLBACK = "fallback"
|
||||
const val IMAGE = "image"
|
||||
const val SERVICE = "service"
|
||||
|
||||
fun parse(tagArray: Array<String>): VideoMeta? {
|
||||
var url: String? = null
|
||||
var mimeType: String? = null
|
||||
var blurhash: String? = null
|
||||
var dim: Dimension? = null
|
||||
var alt: String? = null
|
||||
var hash: String? = null
|
||||
var size: Int? = null
|
||||
var service: String? = null
|
||||
val fallback = mutableListOf<String>()
|
||||
val images = mutableListOf<String>()
|
||||
|
||||
tagArray.forEach {
|
||||
val parts = it.split(" ", limit = 2)
|
||||
val key = parts[0]
|
||||
val value = if (parts.size == 2) parts[1] else ""
|
||||
|
||||
if (value.isNotBlank()) {
|
||||
when (key) {
|
||||
URL -> url = value
|
||||
MIME_TYPE -> mimeType = value
|
||||
BLUR_HASH -> blurhash = value
|
||||
DIMENSION -> dim = Dimension.parse(value)
|
||||
ALT -> alt = value
|
||||
HASH -> hash = value
|
||||
FILE_SIZE -> size = value.toIntOrNull()
|
||||
SERVICE -> service = value
|
||||
FALLBACK -> fallback.add(value)
|
||||
IMAGE -> images.add(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return url?.let {
|
||||
VideoMeta(it, mimeType, blurhash, dim, alt, hash, size, service, fallback, images)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,48 +34,45 @@ class VideoHorizontalEvent(
|
||||
tags: Array<Array<String>>,
|
||||
content: String,
|
||||
sig: HexKey,
|
||||
) : VideoEvent(id, pubKey, createdAt, KIND, tags, content, sig) {
|
||||
) : VideoEvent(id, pubKey, createdAt, KIND, tags, content, sig),
|
||||
RootScope {
|
||||
companion object {
|
||||
const val KIND = 34235
|
||||
const val ALT_DESCRIPTION = "Horizontal Video"
|
||||
|
||||
fun create(
|
||||
url: String,
|
||||
magnetUri: String? = null,
|
||||
mimeType: String? = null,
|
||||
alt: String? = null,
|
||||
hash: String? = null,
|
||||
size: String? = null,
|
||||
size: Int? = null,
|
||||
duration: Int? = null,
|
||||
dimensions: Dimension? = null,
|
||||
blurhash: String? = null,
|
||||
originalHash: String? = null,
|
||||
magnetURI: String? = null,
|
||||
torrentInfoHash: String? = null,
|
||||
sensitiveContent: Boolean? = null,
|
||||
service: String? = null,
|
||||
dTag: String = UUID.randomUUID().toString(),
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (VideoHorizontalEvent) -> Unit,
|
||||
) {
|
||||
create(
|
||||
KIND,
|
||||
dTag,
|
||||
url,
|
||||
magnetUri,
|
||||
mimeType,
|
||||
alt,
|
||||
hash,
|
||||
size,
|
||||
dimensions,
|
||||
blurhash,
|
||||
originalHash,
|
||||
magnetURI,
|
||||
torrentInfoHash,
|
||||
sensitiveContent,
|
||||
ALT_DESCRIPTION,
|
||||
signer,
|
||||
createdAt,
|
||||
onReady,
|
||||
kind = KIND,
|
||||
dTag = dTag,
|
||||
url = url,
|
||||
mimeType = mimeType,
|
||||
alt = alt,
|
||||
hash = hash,
|
||||
size = size,
|
||||
duration = duration,
|
||||
dimensions = dimensions,
|
||||
blurhash = blurhash,
|
||||
sensitiveContent = sensitiveContent,
|
||||
service = service,
|
||||
altDescription = ALT_DESCRIPTION,
|
||||
signer = signer,
|
||||
createdAt = createdAt,
|
||||
onReady = onReady,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -42,41 +42,37 @@ class VideoVerticalEvent(
|
||||
|
||||
fun create(
|
||||
url: String,
|
||||
magnetUri: String? = null,
|
||||
mimeType: String? = null,
|
||||
alt: String? = null,
|
||||
hash: String? = null,
|
||||
size: String? = null,
|
||||
size: Int? = null,
|
||||
duration: Int? = null,
|
||||
dimensions: Dimension? = null,
|
||||
blurhash: String? = null,
|
||||
originalHash: String? = null,
|
||||
magnetURI: String? = null,
|
||||
torrentInfoHash: String? = null,
|
||||
sensitiveContent: Boolean? = null,
|
||||
service: String? = null,
|
||||
dTag: String = UUID.randomUUID().toString(),
|
||||
signer: NostrSigner,
|
||||
createdAt: Long = TimeUtils.now(),
|
||||
onReady: (VideoVerticalEvent) -> Unit,
|
||||
) {
|
||||
create(
|
||||
KIND,
|
||||
dTag,
|
||||
url,
|
||||
magnetUri,
|
||||
mimeType,
|
||||
alt,
|
||||
hash,
|
||||
size,
|
||||
dimensions,
|
||||
blurhash,
|
||||
originalHash,
|
||||
magnetURI,
|
||||
torrentInfoHash,
|
||||
sensitiveContent,
|
||||
ALT_DESCRIPTION,
|
||||
signer,
|
||||
createdAt,
|
||||
onReady,
|
||||
kind = KIND,
|
||||
dTag = dTag,
|
||||
url = url,
|
||||
mimeType = mimeType,
|
||||
alt = alt,
|
||||
hash = hash,
|
||||
size = size,
|
||||
duration = duration,
|
||||
dimensions = dimensions,
|
||||
blurhash = blurhash,
|
||||
sensitiveContent = sensitiveContent,
|
||||
service = service,
|
||||
altDescription = ALT_DESCRIPTION,
|
||||
signer = signer,
|
||||
createdAt = createdAt,
|
||||
onReady = onReady,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user