Migrates alt descriptions from .content to alt tag.

This commit is contained in:
Vitor Pamplona
2023-09-20 16:18:21 -04:00
parent fb0748f4a7
commit 909d3f4fbe
9 changed files with 44 additions and 36 deletions
@@ -1202,7 +1202,7 @@ class Account(
size = headerInfo.size.toString(), size = headerInfo.size.toString(),
dimensions = headerInfo.dim, dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash, blurhash = headerInfo.blurHash,
description = headerInfo.description, alt = headerInfo.alt,
sensitiveContent = headerInfo.sensitiveContent, sensitiveContent = headerInfo.sensitiveContent,
pubKey = keyPair.pubKey.toHexKey() pubKey = keyPair.pubKey.toHexKey()
) )
@@ -1234,7 +1234,7 @@ class Account(
size = headerInfo.size.toString(), size = headerInfo.size.toString(),
dimensions = headerInfo.dim, dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash, blurhash = headerInfo.blurHash,
description = headerInfo.description, alt = headerInfo.alt,
sensitiveContent = headerInfo.sensitiveContent, sensitiveContent = headerInfo.sensitiveContent,
privateKey = keyPair.privKey!! privateKey = keyPair.privKey!!
) )
@@ -1273,7 +1273,7 @@ class Account(
size = headerInfo.size.toString(), size = headerInfo.size.toString(),
dimensions = headerInfo.dim, dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash, blurhash = headerInfo.blurHash,
description = headerInfo.description, alt = headerInfo.alt,
sensitiveContent = headerInfo.sensitiveContent, sensitiveContent = headerInfo.sensitiveContent,
keyPair = keyPair keyPair = keyPair
) )
@@ -1298,7 +1298,7 @@ class Account(
size = headerInfo.size.toString(), size = headerInfo.size.toString(),
dimensions = headerInfo.dim, dimensions = headerInfo.dim,
blurhash = headerInfo.blurHash, blurhash = headerInfo.blurHash,
description = headerInfo.description, alt = headerInfo.alt,
sensitiveContent = headerInfo.sensitiveContent, sensitiveContent = headerInfo.sensitiveContent,
keyPair = keyPair keyPair = keyPair
) )
@@ -16,16 +16,16 @@ class FileHeader(
val size: Int, val size: Int,
val dim: String?, val dim: String?,
val blurHash: String?, val blurHash: String?,
val description: String? = null, val alt: String? = null,
val sensitiveContent: Boolean = false val sensitiveContent: Boolean = false
) { ) {
companion object { companion object {
suspend fun prepare(fileUrl: String, mimeType: String?, description: String?, sensitiveContent: Boolean, onReady: (FileHeader) -> Unit, onError: () -> Unit) { suspend fun prepare(fileUrl: String, mimeType: String?, alt: String?, sensitiveContent: Boolean, onReady: (FileHeader) -> Unit, onError: () -> Unit) {
try { try {
val imageData: ByteArray? = ImageDownloader().waitAndGetImage(fileUrl) val imageData: ByteArray? = ImageDownloader().waitAndGetImage(fileUrl)
if (imageData != null) { if (imageData != null) {
prepare(imageData, fileUrl, mimeType, description, sensitiveContent, onReady, onError) prepare(imageData, fileUrl, mimeType, alt, sensitiveContent, onReady, onError)
} else { } else {
onError() onError()
} }
@@ -39,7 +39,7 @@ class FileHeader(
data: ByteArray, data: ByteArray,
fileUrl: String, fileUrl: String,
mimeType: String?, mimeType: String?,
description: String?, alt: String?,
sensitiveContent: Boolean, sensitiveContent: Boolean,
onReady: (FileHeader) -> Unit, onReady: (FileHeader) -> Unit,
onError: () -> Unit onError: () -> Unit
@@ -79,7 +79,7 @@ class FileHeader(
Pair(null, null) Pair(null, null)
} }
onReady(FileHeader(fileUrl, mimeType, hash, size, dim, blurHash, description, sensitiveContent)) onReady(FileHeader(fileUrl, mimeType, hash, size, dim, blurHash, alt, sensitiveContent))
} catch (e: Exception) { } catch (e: Exception) {
Log.e("ImageDownload", "Couldn't convert image in to File Header: ${e.message}") Log.e("ImageDownload", "Couldn't convert image in to File Header: ${e.message}")
onError() onError()
@@ -26,7 +26,7 @@ open class NewMediaModel : ViewModel() {
var mediaType by mutableStateOf<String?>(null) var mediaType by mutableStateOf<String?>(null)
var selectedServer by mutableStateOf<ServersAvailable?>(null) var selectedServer by mutableStateOf<ServersAvailable?>(null)
var description by mutableStateOf("") var alt by mutableStateOf("")
var sensitiveContent by mutableStateOf(false) var sensitiveContent by mutableStateOf(false)
// Images and Videos // Images and Videos
@@ -79,7 +79,7 @@ open class NewMediaModel : ViewModel() {
uploadingPercentage.value = 0.2f uploadingPercentage.value = 0.2f
uploadingDescription.value = "Loading" uploadingDescription.value = "Loading"
contentResolver.openInputStream(fileUri)?.use { contentResolver.openInputStream(fileUri)?.use {
createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList) createNIP95Record(it.readBytes(), contentType, alt, sensitiveContent, relayList = relayList)
} }
?: run { ?: run {
viewModelScope.launch { viewModelScope.launch {
@@ -103,7 +103,7 @@ open class NewMediaModel : ViewModel() {
createNIP94Record( createNIP94Record(
imageUrl, imageUrl,
mimeType, mimeType,
description, alt,
sensitiveContent, sensitiveContent,
relayList = relayList relayList = relayList
) )
@@ -139,7 +139,7 @@ open class NewMediaModel : ViewModel() {
uploadingDescription.value = null uploadingDescription.value = null
uploadingPercentage.value = 0.0f uploadingPercentage.value = 0.0f
description = "" alt = ""
selectedServer = account?.defaultFileServer selectedServer = account?.defaultFileServer
} }
@@ -147,7 +147,7 @@ open class NewMediaModel : ViewModel() {
return !isUploadingImage && galleryUri != null && selectedServer != null return !isUploadingImage && galleryUri != null && selectedServer != null
} }
fun createNIP94Record(imageUrl: String, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) { fun createNIP94Record(imageUrl: String, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) {
uploadingPercentage.value = 0.40f uploadingPercentage.value = 0.40f
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
uploadingDescription.value = "Server Processing" uploadingDescription.value = "Server Processing"
@@ -166,7 +166,7 @@ open class NewMediaModel : ViewModel() {
imageData, imageData,
imageUrl, imageUrl,
mimeType, mimeType,
description, alt,
sensitiveContent, sensitiveContent,
onReady = { onReady = {
uploadingPercentage.value = 0.90f uploadingPercentage.value = 0.90f
@@ -200,7 +200,7 @@ open class NewMediaModel : ViewModel() {
} }
} }
fun createNIP95Record(bytes: ByteArray, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) { fun createNIP95Record(bytes: ByteArray, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) {
uploadingPercentage.value = 0.30f uploadingPercentage.value = 0.30f
uploadingDescription.value = "Hashing" uploadingDescription.value = "Hashing"
@@ -209,7 +209,7 @@ open class NewMediaModel : ViewModel() {
bytes, bytes,
"", "",
mimeType, mimeType,
description, alt,
sensitiveContent, sensitiveContent,
onReady = { onReady = {
uploadingDescription.value = "Signing" uploadingDescription.value = "Signing"
@@ -287,8 +287,8 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)), .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)),
value = postViewModel.description, value = postViewModel.alt,
onValueChange = { postViewModel.description = it }, onValueChange = { postViewModel.alt = it },
placeholder = { placeholder = {
Text( Text(
text = stringResource(R.string.content_description_example), text = stringResource(R.string.content_description_example),
@@ -338,8 +338,8 @@ fun NewPostView(
ImageVideoDescription( ImageVideoDescription(
url, url,
account.defaultFileServer, account.defaultFileServer,
onAdd = { description, server, sensitiveContent -> onAdd = { alt, server, sensitiveContent ->
postViewModel.upload(url, description, sensitiveContent, server, context, relayList) postViewModel.upload(url, alt, sensitiveContent, server, context, relayList)
account.changeDefaultFileServer(server) account.changeDefaultFileServer(server)
}, },
onCancel = { onCancel = {
@@ -299,7 +299,7 @@ open class NewPostViewModel() : ViewModel() {
cancel() cancel()
} }
fun upload(galleryUri: Uri, description: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List<Relay>? = null) { fun upload(galleryUri: Uri, alt: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List<Relay>? = null) {
isUploadingImage = true isUploadingImage = true
contentToAddUrl = null contentToAddUrl = null
@@ -314,7 +314,7 @@ open class NewPostViewModel() : ViewModel() {
onReady = { fileUri, contentType, size -> onReady = { fileUri, contentType, size ->
if (server == ServersAvailable.NIP95) { if (server == ServersAvailable.NIP95) {
contentResolver.openInputStream(fileUri)?.use { contentResolver.openInputStream(fileUri)?.use {
createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList) createNIP95Record(it.readBytes(), contentType, alt, sensitiveContent, relayList = relayList)
} }
} else { } else {
ImageUploader.uploadImage( ImageUploader.uploadImage(
@@ -325,7 +325,7 @@ open class NewPostViewModel() : ViewModel() {
contentResolver = contentResolver, contentResolver = contentResolver,
onSuccess = { imageUrl, mimeType -> onSuccess = { imageUrl, mimeType ->
if (isNIP94Server(server)) { if (isNIP94Server(server)) {
createNIP94Record(imageUrl, mimeType, description, sensitiveContent) createNIP94Record(imageUrl, mimeType, alt, sensitiveContent)
} else { } else {
isUploadingImage = false isUploadingImage = false
message = TextFieldValue(message.text + "\n\n" + imageUrl) message = TextFieldValue(message.text + "\n\n" + imageUrl)
@@ -537,13 +537,13 @@ open class NewPostViewModel() : ViewModel() {
} }
} }
fun createNIP94Record(imageUrl: String, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) { fun createNIP94Record(imageUrl: String, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
// Images don't seem to be ready immediately after upload // Images don't seem to be ready immediately after upload
FileHeader.prepare( FileHeader.prepare(
imageUrl, imageUrl,
mimeType, mimeType,
description, alt,
sensitiveContent, sensitiveContent,
onReady = { onReady = {
val note = account?.sendHeader(it, relayList = relayList) val note = account?.sendHeader(it, relayList = relayList)
@@ -568,13 +568,13 @@ open class NewPostViewModel() : ViewModel() {
} }
} }
fun createNIP95Record(bytes: ByteArray, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) { fun createNIP95Record(bytes: ByteArray, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List<Relay>? = null) {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
FileHeader.prepare( FileHeader.prepare(
bytes, bytes,
"", "",
mimeType, mimeType,
description, alt,
sensitiveContent, sensitiveContent,
onReady = { onReady = {
val nip95 = account?.createNip95(bytes, headerInfo = it) val nip95 = account?.createNip95(bytes, headerInfo = it)
@@ -3343,7 +3343,7 @@ fun FileHeaderDisplay(note: Note, roundedCorner: Boolean, accountViewModel: Acco
val blurHash = event.blurhash() val blurHash = event.blurhash()
val hash = event.hash() val hash = event.hash()
val dimensions = event.dimensions() val dimensions = event.dimensions()
val description = event.content val description = event.alt() ?: event.content
val isImage = imageExtensions.any { fullUrl.split("?")[0].lowercase().endsWith(it) } val isImage = imageExtensions.any { fullUrl.split("?")[0].lowercase().endsWith(it) }
val uri = note.toNostrUri() val uri = note.toNostrUri()
@@ -3407,7 +3407,7 @@ private fun ObserverAndRenderNIP95(
val localDir = note?.idHex?.let { File(File(appContext.cacheDir, "NIP95"), it) } val localDir = note?.idHex?.let { File(File(appContext.cacheDir, "NIP95"), it) }
val blurHash = eventHeader.blurhash() val blurHash = eventHeader.blurhash()
val dimensions = eventHeader.dimensions() val dimensions = eventHeader.dimensions()
val description = eventHeader.content val description = eventHeader.alt() ?: eventHeader.content
val mimeType = eventHeader.mimeType() val mimeType = eventHeader.mimeType()
val newContent = if (mimeType?.startsWith("image") == true) { val newContent = if (mimeType?.startsWith("image") == true) {
@@ -22,6 +22,7 @@ class FileHeaderEvent(
fun mimeType() = tags.firstOrNull { it.size > 1 && it[0] == MIME_TYPE }?.get(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 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 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 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 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 torrentInfoHash() = tags.firstOrNull { it.size > 1 && it[0] == TORRENT_INFOHASH }?.get(1)
@@ -41,11 +42,12 @@ class FileHeaderEvent(
private const val MAGNET_URI = "magnet" private const val MAGNET_URI = "magnet"
private const val TORRENT_INFOHASH = "i" private const val TORRENT_INFOHASH = "i"
private const val BLUR_HASH = "blurhash" private const val BLUR_HASH = "blurhash"
private const val ALT = "alt"
fun create( fun create(
url: String, url: String,
mimeType: String? = null, mimeType: String? = null,
description: String? = null, alt: String? = null,
hash: String? = null, hash: String? = null,
size: String? = null, size: String? = null,
dimensions: String? = null, dimensions: String? = null,
@@ -60,11 +62,13 @@ class FileHeaderEvent(
val tags = listOfNotNull( val tags = listOfNotNull(
listOf(URL, url), listOf(URL, url),
mimeType?.let { listOf(MIME_TYPE, mimeType) }, mimeType?.let { listOf(MIME_TYPE, mimeType) },
alt?.let { listOf(ALT, it) },
hash?.let { listOf(HASH, it) }, hash?.let { listOf(HASH, it) },
size?.let { listOf(FILE_SIZE, it) }, size?.let { listOf(FILE_SIZE, it) },
dimensions?.let { listOf(DIMENSION, it) }, dimensions?.let { listOf(DIMENSION, it) },
blurhash?.let { listOf(BLUR_HASH, it) }, blurhash?.let { listOf(BLUR_HASH, it) },
magnetURI?.let { listOf(MAGNET_URI, it) }, magnetURI?.let { listOf(MAGNET_URI, it) },
torrentInfoHash?.let { listOf(TORRENT_INFOHASH, it) }, torrentInfoHash?.let { listOf(TORRENT_INFOHASH, it) },
encryptionKey?.let { listOf(ENCRYPTION_KEY, it.key, it.nonce) }, encryptionKey?.let { listOf(ENCRYPTION_KEY, it.key, it.nonce) },
sensitiveContent?.let { sensitiveContent?.let {
@@ -76,7 +80,7 @@ class FileHeaderEvent(
} }
) )
val content = description ?: "" val content = alt ?: ""
val pubKey = keyPair.pubKey.toHexKey() val pubKey = keyPair.pubKey.toHexKey()
val id = generateId(pubKey, createdAt, kind, tags, content) val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey)
@@ -22,6 +22,7 @@ class FileStorageHeaderEvent(
fun mimeType() = tags.firstOrNull { it.size > 1 && it[0] == MIME_TYPE }?.get(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 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 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 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 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 torrentInfoHash() = tags.firstOrNull { it.size > 1 && it[0] == TORRENT_INFOHASH }?.get(1)
@@ -38,11 +39,12 @@ class FileStorageHeaderEvent(
private const val MAGNET_URI = "magnet" private const val MAGNET_URI = "magnet"
private const val TORRENT_INFOHASH = "i" private const val TORRENT_INFOHASH = "i"
private const val BLUR_HASH = "blurhash" private const val BLUR_HASH = "blurhash"
private const val ALT = "alt"
fun create( fun create(
storageEvent: FileStorageEvent, storageEvent: FileStorageEvent,
mimeType: String? = null, mimeType: String? = null,
description: String? = null, alt: String? = null,
hash: String? = null, hash: String? = null,
size: String? = null, size: String? = null,
dimensions: String? = null, dimensions: String? = null,
@@ -57,6 +59,7 @@ class FileStorageHeaderEvent(
val tags = listOfNotNull( val tags = listOfNotNull(
listOf("e", storageEvent.id), listOf("e", storageEvent.id),
mimeType?.let { listOf(MIME_TYPE, mimeType) }, mimeType?.let { listOf(MIME_TYPE, mimeType) },
alt?.let { listOf(ALT, it) },
hash?.let { listOf(HASH, it) }, hash?.let { listOf(HASH, it) },
size?.let { listOf(FILE_SIZE, it) }, size?.let { listOf(FILE_SIZE, it) },
dimensions?.let { listOf(DIMENSION, it) }, dimensions?.let { listOf(DIMENSION, it) },
@@ -73,7 +76,7 @@ class FileStorageHeaderEvent(
} }
) )
val content = description ?: "" val content = alt ?: ""
val id = generateId(pubKey, createdAt, kind, tags, content) val id = generateId(pubKey, createdAt, kind, tags, content)
return FileStorageHeaderEvent(id.toHexKey(), pubKey, createdAt, tags, content, "") return FileStorageHeaderEvent(id.toHexKey(), pubKey, createdAt, tags, content, "")
} }
@@ -81,7 +84,7 @@ class FileStorageHeaderEvent(
fun create( fun create(
storageEvent: FileStorageEvent, storageEvent: FileStorageEvent,
mimeType: String? = null, mimeType: String? = null,
description: String? = null, alt: String? = null,
hash: String? = null, hash: String? = null,
size: String? = null, size: String? = null,
dimensions: String? = null, dimensions: String? = null,
@@ -97,6 +100,7 @@ class FileStorageHeaderEvent(
listOf("e", storageEvent.id), listOf("e", storageEvent.id),
mimeType?.let { listOf(MIME_TYPE, mimeType) }, mimeType?.let { listOf(MIME_TYPE, mimeType) },
hash?.let { listOf(HASH, it) }, hash?.let { listOf(HASH, it) },
alt?.let { listOf(ALT, it) },
size?.let { listOf(FILE_SIZE, it) }, size?.let { listOf(FILE_SIZE, it) },
dimensions?.let { listOf(DIMENSION, it) }, dimensions?.let { listOf(DIMENSION, it) },
blurhash?.let { listOf(BLUR_HASH, it) }, blurhash?.let { listOf(BLUR_HASH, it) },
@@ -112,7 +116,7 @@ class FileStorageHeaderEvent(
} }
) )
val content = description ?: "" val content = alt ?: ""
val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey() val pubKey = CryptoUtils.pubkeyCreate(privateKey).toHexKey()
val id = generateId(pubKey, createdAt, kind, tags, content) val id = generateId(pubKey, createdAt, kind, tags, content)
val sig = CryptoUtils.sign(id, privateKey) val sig = CryptoUtils.sign(id, privateKey)