From 909d3f4fbe233aac8b587732f2bf3bd0fe3b1da9 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 20 Sep 2023 16:18:21 -0400 Subject: [PATCH] Migrates alt descriptions from .content to alt tag. --- .../com/vitorpamplona/amethyst/model/Account.kt | 8 ++++---- .../vitorpamplona/amethyst/service/FileHeader.kt | 10 +++++----- .../amethyst/ui/actions/NewMediaModel.kt | 16 ++++++++-------- .../amethyst/ui/actions/NewMediaView.kt | 4 ++-- .../amethyst/ui/actions/NewPostView.kt | 4 ++-- .../amethyst/ui/actions/NewPostViewModel.kt | 14 +++++++------- .../amethyst/ui/note/NoteCompose.kt | 4 ++-- .../quartz/events/FileHeaderEvent.kt | 8 ++++++-- .../quartz/events/FileStorageHeaderEvent.kt | 12 ++++++++---- 9 files changed, 44 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index c182a34ac..0fc5eff72 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -1202,7 +1202,7 @@ class Account( size = headerInfo.size.toString(), dimensions = headerInfo.dim, blurhash = headerInfo.blurHash, - description = headerInfo.description, + alt = headerInfo.alt, sensitiveContent = headerInfo.sensitiveContent, pubKey = keyPair.pubKey.toHexKey() ) @@ -1234,7 +1234,7 @@ class Account( size = headerInfo.size.toString(), dimensions = headerInfo.dim, blurhash = headerInfo.blurHash, - description = headerInfo.description, + alt = headerInfo.alt, sensitiveContent = headerInfo.sensitiveContent, privateKey = keyPair.privKey!! ) @@ -1273,7 +1273,7 @@ class Account( size = headerInfo.size.toString(), dimensions = headerInfo.dim, blurhash = headerInfo.blurHash, - description = headerInfo.description, + alt = headerInfo.alt, sensitiveContent = headerInfo.sensitiveContent, keyPair = keyPair ) @@ -1298,7 +1298,7 @@ class Account( size = headerInfo.size.toString(), dimensions = headerInfo.dim, blurhash = headerInfo.blurHash, - description = headerInfo.description, + alt = headerInfo.alt, sensitiveContent = headerInfo.sensitiveContent, keyPair = keyPair ) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt index d03cd7da1..b9c247215 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/FileHeader.kt @@ -16,16 +16,16 @@ class FileHeader( val size: Int, val dim: String?, val blurHash: String?, - val description: String? = null, + val alt: String? = null, val sensitiveContent: Boolean = false ) { 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 { val imageData: ByteArray? = ImageDownloader().waitAndGetImage(fileUrl) if (imageData != null) { - prepare(imageData, fileUrl, mimeType, description, sensitiveContent, onReady, onError) + prepare(imageData, fileUrl, mimeType, alt, sensitiveContent, onReady, onError) } else { onError() } @@ -39,7 +39,7 @@ class FileHeader( data: ByteArray, fileUrl: String, mimeType: String?, - description: String?, + alt: String?, sensitiveContent: Boolean, onReady: (FileHeader) -> Unit, onError: () -> Unit @@ -79,7 +79,7 @@ class FileHeader( 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) { Log.e("ImageDownload", "Couldn't convert image in to File Header: ${e.message}") onError() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaModel.kt index 151e2e3fc..580a13c35 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaModel.kt @@ -26,7 +26,7 @@ open class NewMediaModel : ViewModel() { var mediaType by mutableStateOf(null) var selectedServer by mutableStateOf(null) - var description by mutableStateOf("") + var alt by mutableStateOf("") var sensitiveContent by mutableStateOf(false) // Images and Videos @@ -79,7 +79,7 @@ open class NewMediaModel : ViewModel() { uploadingPercentage.value = 0.2f uploadingDescription.value = "Loading" contentResolver.openInputStream(fileUri)?.use { - createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList) + createNIP95Record(it.readBytes(), contentType, alt, sensitiveContent, relayList = relayList) } ?: run { viewModelScope.launch { @@ -103,7 +103,7 @@ open class NewMediaModel : ViewModel() { createNIP94Record( imageUrl, mimeType, - description, + alt, sensitiveContent, relayList = relayList ) @@ -139,7 +139,7 @@ open class NewMediaModel : ViewModel() { uploadingDescription.value = null uploadingPercentage.value = 0.0f - description = "" + alt = "" selectedServer = account?.defaultFileServer } @@ -147,7 +147,7 @@ open class NewMediaModel : ViewModel() { return !isUploadingImage && galleryUri != null && selectedServer != null } - fun createNIP94Record(imageUrl: String, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List? = null) { + fun createNIP94Record(imageUrl: String, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List? = null) { uploadingPercentage.value = 0.40f viewModelScope.launch(Dispatchers.IO) { uploadingDescription.value = "Server Processing" @@ -166,7 +166,7 @@ open class NewMediaModel : ViewModel() { imageData, imageUrl, mimeType, - description, + alt, sensitiveContent, onReady = { uploadingPercentage.value = 0.90f @@ -200,7 +200,7 @@ open class NewMediaModel : ViewModel() { } } - fun createNIP95Record(bytes: ByteArray, mimeType: String?, description: String, sensitiveContent: Boolean, relayList: List? = null) { + fun createNIP95Record(bytes: ByteArray, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List? = null) { uploadingPercentage.value = 0.30f uploadingDescription.value = "Hashing" @@ -209,7 +209,7 @@ open class NewMediaModel : ViewModel() { bytes, "", mimeType, - description, + alt, sensitiveContent, onReady = { uploadingDescription.value = "Signing" diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt index 2e86c9997..4b044dfc9 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewMediaView.kt @@ -287,8 +287,8 @@ fun ImageVideoPost(postViewModel: NewMediaModel, accountViewModel: AccountViewMo modifier = Modifier .fillMaxWidth() .windowInsetsPadding(WindowInsets(0.dp, 0.dp, 0.dp, 0.dp)), - value = postViewModel.description, - onValueChange = { postViewModel.description = it }, + value = postViewModel.alt, + onValueChange = { postViewModel.alt = it }, placeholder = { Text( text = stringResource(R.string.content_description_example), diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt index c16dedb45..5974935c5 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostView.kt @@ -338,8 +338,8 @@ fun NewPostView( ImageVideoDescription( url, account.defaultFileServer, - onAdd = { description, server, sensitiveContent -> - postViewModel.upload(url, description, sensitiveContent, server, context, relayList) + onAdd = { alt, server, sensitiveContent -> + postViewModel.upload(url, alt, sensitiveContent, server, context, relayList) account.changeDefaultFileServer(server) }, onCancel = { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt index b7d82e07c..81f65d224 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/actions/NewPostViewModel.kt @@ -299,7 +299,7 @@ open class NewPostViewModel() : ViewModel() { cancel() } - fun upload(galleryUri: Uri, description: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List? = null) { + fun upload(galleryUri: Uri, alt: String, sensitiveContent: Boolean, server: ServersAvailable, context: Context, relayList: List? = null) { isUploadingImage = true contentToAddUrl = null @@ -314,7 +314,7 @@ open class NewPostViewModel() : ViewModel() { onReady = { fileUri, contentType, size -> if (server == ServersAvailable.NIP95) { contentResolver.openInputStream(fileUri)?.use { - createNIP95Record(it.readBytes(), contentType, description, sensitiveContent, relayList = relayList) + createNIP95Record(it.readBytes(), contentType, alt, sensitiveContent, relayList = relayList) } } else { ImageUploader.uploadImage( @@ -325,7 +325,7 @@ open class NewPostViewModel() : ViewModel() { contentResolver = contentResolver, onSuccess = { imageUrl, mimeType -> if (isNIP94Server(server)) { - createNIP94Record(imageUrl, mimeType, description, sensitiveContent) + createNIP94Record(imageUrl, mimeType, alt, sensitiveContent) } else { isUploadingImage = false 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? = null) { + fun createNIP94Record(imageUrl: String, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List? = null) { viewModelScope.launch(Dispatchers.IO) { // Images don't seem to be ready immediately after upload FileHeader.prepare( imageUrl, mimeType, - description, + alt, sensitiveContent, onReady = { 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? = null) { + fun createNIP95Record(bytes: ByteArray, mimeType: String?, alt: String, sensitiveContent: Boolean, relayList: List? = null) { viewModelScope.launch(Dispatchers.IO) { FileHeader.prepare( bytes, "", mimeType, - description, + alt, sensitiveContent, onReady = { val nip95 = account?.createNip95(bytes, headerInfo = it) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 5b1dc0e80..09def4997 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -3343,7 +3343,7 @@ fun FileHeaderDisplay(note: Note, roundedCorner: Boolean, accountViewModel: Acco val blurHash = event.blurhash() val hash = event.hash() 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 uri = note.toNostrUri() @@ -3407,7 +3407,7 @@ private fun ObserverAndRenderNIP95( val localDir = note?.idHex?.let { File(File(appContext.cacheDir, "NIP95"), it) } val blurHash = eventHeader.blurhash() val dimensions = eventHeader.dimensions() - val description = eventHeader.content + val description = eventHeader.alt() ?: eventHeader.content val mimeType = eventHeader.mimeType() val newContent = if (mimeType?.startsWith("image") == true) { diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt index 92a0dd0f0..da0035ea3 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileHeaderEvent.kt @@ -22,6 +22,7 @@ class FileHeaderEvent( 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) @@ -41,11 +42,12 @@ class FileHeaderEvent( private const val MAGNET_URI = "magnet" private const val TORRENT_INFOHASH = "i" private const val BLUR_HASH = "blurhash" + private const val ALT = "alt" fun create( url: String, mimeType: String? = null, - description: String? = null, + alt: String? = null, hash: String? = null, size: String? = null, dimensions: String? = null, @@ -60,11 +62,13 @@ class FileHeaderEvent( val tags = listOfNotNull( listOf(URL, url), mimeType?.let { listOf(MIME_TYPE, mimeType) }, + alt?.let { listOf(ALT, it) }, hash?.let { listOf(HASH, it) }, size?.let { listOf(FILE_SIZE, it) }, dimensions?.let { listOf(DIMENSION, it) }, blurhash?.let { listOf(BLUR_HASH, it) }, magnetURI?.let { listOf(MAGNET_URI, it) }, + torrentInfoHash?.let { listOf(TORRENT_INFOHASH, it) }, encryptionKey?.let { listOf(ENCRYPTION_KEY, it.key, it.nonce) }, sensitiveContent?.let { @@ -76,7 +80,7 @@ class FileHeaderEvent( } ) - val content = description ?: "" + val content = alt ?: "" val pubKey = keyPair.pubKey.toHexKey() val id = generateId(pubKey, createdAt, kind, tags, content) val sig = if (keyPair.privKey == null) null else CryptoUtils.sign(id, keyPair.privKey) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt index 2554ac1ad..140c78d96 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/events/FileStorageHeaderEvent.kt @@ -22,6 +22,7 @@ class FileStorageHeaderEvent( 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) @@ -38,11 +39,12 @@ class FileStorageHeaderEvent( private const val MAGNET_URI = "magnet" private const val TORRENT_INFOHASH = "i" private const val BLUR_HASH = "blurhash" + private const val ALT = "alt" fun create( storageEvent: FileStorageEvent, mimeType: String? = null, - description: String? = null, + alt: String? = null, hash: String? = null, size: String? = null, dimensions: String? = null, @@ -57,6 +59,7 @@ class FileStorageHeaderEvent( val tags = listOfNotNull( listOf("e", storageEvent.id), mimeType?.let { listOf(MIME_TYPE, mimeType) }, + alt?.let { listOf(ALT, it) }, hash?.let { listOf(HASH, it) }, size?.let { listOf(FILE_SIZE, 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) return FileStorageHeaderEvent(id.toHexKey(), pubKey, createdAt, tags, content, "") } @@ -81,7 +84,7 @@ class FileStorageHeaderEvent( fun create( storageEvent: FileStorageEvent, mimeType: String? = null, - description: String? = null, + alt: String? = null, hash: String? = null, size: String? = null, dimensions: String? = null, @@ -97,6 +100,7 @@ class FileStorageHeaderEvent( listOf("e", storageEvent.id), mimeType?.let { listOf(MIME_TYPE, mimeType) }, hash?.let { listOf(HASH, it) }, + alt?.let { listOf(ALT, it) }, size?.let { listOf(FILE_SIZE, it) }, dimensions?.let { listOf(DIMENSION, 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 id = generateId(pubKey, createdAt, kind, tags, content) val sig = CryptoUtils.sign(id, privateKey)