Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ ktlint_standard_import-ordering = disabled
ktlint_standard_string-template-indent = disabled
ktlint_standard_backing-property-naming = disabled
ktlint_standard_no-consecutive-comments = disabled

[nitrogen/generated/**/*.kt]
ktlint = disabled
2 changes: 2 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ disabled_rules:
- trailing_whitespace
- todo
- unused_optional_binding
- opening_brace
- trailing_comma

reporter: github-actions-logging
37 changes: 37 additions & 0 deletions android/src/main/java/com/margelo/nitro/rive/HTTPLoader.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.margelo.nitro.rive

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.net.HttpURLConnection
import java.net.MalformedURLException
import java.net.URL

sealed class HTTPLoaderException(message: String) : Exception(message) {
class InvalidURL(url: String) : HTTPLoaderException("Invalid URL: $url")
class HttpError(val statusCode: Int, url: String) :
HTTPLoaderException("HTTP error $statusCode for $url")
}

object HTTPLoader {
suspend fun downloadBytes(url: String): ByteArray = withContext(Dispatchers.IO) {
val urlObj = try {
URL(url)
} catch (e: MalformedURLException) {
throw HTTPLoaderException.InvalidURL(url)
}
val connection = urlObj.openConnection() as HttpURLConnection

try {
connection.requestMethod = "GET"
val statusCode = connection.responseCode

if (statusCode !in 200..299) {
throw HTTPLoaderException.HttpError(statusCode, url)
}

connection.inputStream.use { it.readBytes() }
} finally {
connection.disconnect()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File as JavaFile
import java.net.URI
import java.net.URL

data class FileAndCache(
val file: File,
Expand Down Expand Up @@ -45,8 +44,7 @@ class HybridRiveFileFactory : HybridRiveFileFactorySpec() {
return Promise.async {
try {
val fileAndCache = withContext(Dispatchers.IO) {
val urlObj = URL(url)
val riveData = urlObj.readBytes()
val riveData = HTTPLoader.downloadBytes(url)
buildRiveFile(riveData, referencedAssets)
}

Expand All @@ -56,7 +54,7 @@ class HybridRiveFileFactory : HybridRiveFileFactorySpec() {
hybridRiveFile.assetLoader = fileAndCache.loader
hybridRiveFile
} catch (e: Exception) {
throw Error("Failed to download Rive file: ${e.message}")
throw Error("Failed to download Rive file: ${e.message}", e)
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions android/src/main/java/com/margelo/nitro/rive/HybridRiveImage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.margelo.nitro.rive

import androidx.annotation.Keep
import app.rive.runtime.kotlin.core.RiveRenderImage
import com.facebook.proguard.annotations.DoNotStrip

@Keep
@DoNotStrip
class HybridRiveImage(
val renderImage: RiveRenderImage,
private val dataSize: Int
) : HybridRiveImageSpec() {
override val byteSize: Double
get() = dataSize.toDouble()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.margelo.nitro.rive

import androidx.annotation.Keep
import app.rive.runtime.kotlin.core.RiveRenderImage
import com.facebook.proguard.annotations.DoNotStrip
import com.margelo.nitro.core.Promise

@Keep
@DoNotStrip
class HybridRiveImageFactory : HybridRiveImageFactorySpec() {
override fun loadFromURLAsync(url: String): Promise<HybridRiveImageSpec> {
return Promise.async {
try {
val imageData = HTTPLoader.downloadBytes(url)
val renderImage = RiveRenderImage.fromEncoded(imageData)
Comment thread
mfazekas marked this conversation as resolved.
HybridRiveImage(renderImage, imageData.size)
} catch (e: Exception) {
throw Exception("Failed to load image from URL: $url - ${e.message}", e)
Comment thread
mfazekas marked this conversation as resolved.
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ReferencedAssetLoader {
file.readBytes()
}
"http", "https" -> {
URL(url).readBytes()
HTTPLoader.downloadBytes(url)
}
else -> {
logError("Unsupported URL scheme: ${uri.scheme}")
Expand Down Expand Up @@ -181,14 +181,28 @@ class ReferencedAssetLoader {

private fun processAssetBytes(bytes: ByteArray, asset: FileAsset) {
when (asset) {
is ImageAsset -> asset.image = RiveRenderImage.make(bytes)
is ImageAsset -> asset.image = RiveRenderImage.fromEncoded(bytes)
is FontAsset -> asset.font = RiveFont.make(bytes)
is AudioAsset -> asset.audio = RiveAudio.make(bytes)
}
}

private fun handlePreloadedImage(image: HybridRiveImageSpec, asset: FileAsset) {
if (asset is ImageAsset && image is HybridRiveImage) {
asset.image = image.renderImage
}
}

private fun loadAsset(assetData: ResolvedReferencedAsset, asset: FileAsset, context: Context): Deferred<Unit> {
val deferred = CompletableDeferred<Unit>()

// Check for pre-loaded image first
if (assetData.image != null) {
handlePreloadedImage(assetData.image, asset)
deferred.complete(Unit)
return deferred
}

val listener: (ByteArray?) -> Unit = { bytes ->
if (bytes != null) {
processAssetBytes(bytes, asset)
Expand Down
Loading
Loading