Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion NitroFs.podspec → NitroFS.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Pod::Spec.new do |s|
s.license = package["license"]
s.authors = package["author"]

s.platforms = { :ios => min_ios_version_supported, :visionos => 1.0 }
s.platforms = { :ios => min_ios_version_supported }
s.source = { :git => "https://github.com/patrickkabwe/react-native-nitro-fs.git", :tag => "#{s.version}" }

s.source_files = [
Expand Down
22 changes: 19 additions & 3 deletions android/src/main/java/com/nitrofs/FileDownloader.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.nitrofs

import android.util.Log
import com.margelo.nitro.nitrofs.NitroFile
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.onDownload
import io.ktor.client.request.prepareGet
import io.ktor.http.HttpMethod
import io.ktor.http.isSuccess
import io.ktor.util.cio.writeChannel
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.copyAndClose
Expand All @@ -16,16 +19,18 @@ import java.io.File
class FileDownloader {
suspend fun downloadFile(
serverUrl: String,
fileName: String,
destinationPath: String,
onProgress: ((Double, Double) -> Unit)?
) {
): NitroFile? {
var contentType = ""
val outputFile = File(destinationPath)
outputFile.parentFile?.mkdirs()

val client = HttpClient(OkHttp)


client.use { it
it.prepareGet("$serverUrl/$fileName") {
it.prepareGet(serverUrl) {
method = HttpMethod.Get
onDownload { totalBytesSent, contentLength ->
if (totalBytesSent > 0 && contentLength != null){
Expand All @@ -37,9 +42,20 @@ class FileDownloader {
}
}
}.execute { response ->
Log.d("TAG", "${response.status.isSuccess()} ${response.status.value} $serverUrl")
if (!response.status.isSuccess()) {
throw RuntimeException("HTTP ${response.status.value}: Failed to download file")
}
contentType = response.headers["Content-Type"] ?: "application/octet-stream"
val channel: ByteReadChannel = response.body()
channel.copyAndClose(outputFile.writeChannel())
}
}

return NitroFile(
name = outputFile.name,
path = outputFile.absolutePath,
mimeType = contentType
)
}
}
8 changes: 1 addition & 7 deletions android/src/main/java/com/nitrofs/HybridNitroFS.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,12 @@ class HybridNitroFS: HybridNitroFSSpec() {

override fun downloadFile(
serverUrl: String,
fileName: String,
destinationPath: String,
onProgress: ((Double, Double) -> Unit)?
): Promise<NitroFile> {
return Promise.async(ioScope) {
try {
nitroFsImpl.downloadFile(serverUrl, fileName, destinationPath, onProgress)
NitroFile(
name = fileName,
path = destinationPath,
mimeType = "",
)
nitroFsImpl.downloadFile(serverUrl, destinationPath, onProgress)
} catch (e: Exception) {
Log.e("NitroFS", "Error downloading file: ${e.message}")
throw Error(e)
Expand Down
11 changes: 7 additions & 4 deletions android/src/main/java/com/nitrofs/NitroFSImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,16 +92,19 @@ class NitroFSImpl(val context: ReactApplicationContext) {

suspend fun downloadFile(
serverUrl: String,
fileName: String,
destinationPath: String,
onProgress: ((Double, Double) -> Unit)?
) {
fileDownloader.downloadFile(
): NitroFile {
val file = fileDownloader.downloadFile(
serverUrl,
fileName,
destinationPath,
onProgress
)
if (file != null) {
return file
} else {
throw RuntimeException("Failed to download file from: $serverUrl")
}
}

fun getFileEncoding(encoding: NitroFileEncoding): Charset {
Expand Down
9 changes: 4 additions & 5 deletions example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const uploadURL = Platform.select({
});

const downloadURL = Platform.select({
ios: 'http://localhost:5100/download',
android: 'http://10.0.2.2:5100/download',
default: 'http://localhost:5100/download',
ios: 'http://localhost:5100/download/dummyfile.txt',
android: 'http://10.0.2.2:5100/download/dummyfile.txt',
default: 'http://localhost:5100/download/dummyfile.txt',
});

const fileToUpload = Platform.select({
Expand Down Expand Up @@ -119,7 +119,7 @@ function App(): React.JSX.Element {
mimeType: 'text/plain',
path: fileToUpload,
},
{url: uploadURL, method: 'POST', field: 'file'},
{ url: uploadURL, method: 'POST', field: 'file'},
(uploadedBytes, totalBytes) => {
const progress = (uploadedBytes / totalBytes) * 100;
setUploadProgress(Math.round(progress));
Expand All @@ -140,7 +140,6 @@ function App(): React.JSX.Element {
onPress={() => {
NitroFS.downloadFile(
downloadURL,
'dummyfile.txt',
NitroFS.DOWNLOAD_DIR + '/dummyfile.txt',
(downloadedBytes, totalBytes) => {
const progress = (downloadedBytes / totalBytes) * 100;
Expand Down
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PODS:
- hermes-engine (0.78.0):
- hermes-engine/Pre-built (= 0.78.0)
- hermes-engine/Pre-built (0.78.0)
- NitroFS (0.2.5):
- NitroFS (0.4.2):
- DoubleConversion
- glog
- hermes-engine
Expand Down Expand Up @@ -1798,7 +1798,7 @@ SPEC CHECKSUMS:
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8
hermes-engine: b417d2b2aee3b89b58e63e23a51e02be91dc876d
NitroFS: 979894cea0ce1469f6baf81d4e755e2209b05749
NitroFS: 1bb934dabe27fe3c8d7838cb638cc4bb9a40548c
NitroModules: 5cc92d3b0baf1124ed8136a015924eea03db912e
RCT-Folly: e78785aa9ba2ed998ea4151e314036f6c49e6d82
RCTDeprecation: b2eecf2d60216df56bc5e6be5f063826d3c1ee35
Expand Down
13 changes: 6 additions & 7 deletions ios/HybridNitroFs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class HybridNitroFS: HybridNitroFSSpec {
try self.nitroFSImpl.writeFile(path: filepath, data: data, encoding: encoding)
} catch {
os_log("Failed to write file content: \(error.localizedDescription)")
throw NitroFSError.nitroFSWriteFailed(message: "Failed to wriote file content to disk")
throw NitroFSError.fileError(message: "Failed to write file content to disk")
}
}
}
Expand All @@ -41,7 +41,7 @@ class HybridNitroFS: HybridNitroFSSpec {
return try self.nitroFSImpl.readFile(path: path, encoding: encoding)
} catch {
os_log("Failed to read file content: \(error.localizedDescription)")
throw NitroFSError.nitroFSWriteFailed(message: "Failed to write file content to disk")
throw NitroFSError.fileError(message: "Failed to write file content to disk")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix incorrect error message in readFile method.

The error message says "write" but this is in the readFile method, so it should say "read".

-                throw  NitroFSError.fileError(message: "Failed to write file content to disk")
+                throw  NitroFSError.fileError(message: "Failed to read file content from disk")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
throw NitroFSError.fileError(message: "Failed to write file content to disk")
throw NitroFSError.fileError(message: "Failed to read file content from disk")
🤖 Prompt for AI Agents
In ios/HybridNitroFs.swift at line 44, the error message in the readFile method
incorrectly states "Failed to write file content to disk." Change the message to
"Failed to read file content from disk" to accurately reflect the read operation
failure.

}
}
}
Expand All @@ -52,7 +52,7 @@ class HybridNitroFS: HybridNitroFSSpec {
try self.nitroFSImpl.copy(source: srcPath, destination: destPath)
} catch {
os_log("Failed to copy file content: \(error.localizedDescription)")
throw NitroFSError.nitroFSWriteFailed(message: "Failed to copy file file content to disk")
throw NitroFSError.fileError(message: "Failed to copy file file content to disk")
}
}
}
Expand All @@ -63,7 +63,7 @@ class HybridNitroFS: HybridNitroFSSpec {
try self.nitroFSImpl.copy(source: srcPath, destination: destPath)
} catch {
os_log("Failed to copy file or directory: \(error.localizedDescription)")
throw NitroFSError.nitroFSWriteFailed(message: "Failed to copy file or directory content to disk")
throw NitroFSError.fileError(message: "Failed to copy file or directory content to disk")
}
}
}
Expand Down Expand Up @@ -99,7 +99,7 @@ class HybridNitroFS: HybridNitroFSSpec {
} catch {
os_log("Failed to get stat: \(error.localizedDescription)")

throw NitroFSError.nitroFSInvalidEncoding(message: "Failed to get stat: \(error.localizedDescription)")
throw NitroFSError.encodingError(message: "Failed to get stat: \(error.localizedDescription)")
}
}
}
Expand All @@ -123,12 +123,11 @@ class HybridNitroFS: HybridNitroFSSpec {
}
}

func downloadFile(serverUrl: String, fileName: String, destinationPath: String, onProgress: ((Double, Double) -> Void)?) throws -> NitroModules.Promise<NitroFile> {
func downloadFile(serverUrl: String, destinationPath: String, onProgress: ((Double, Double) -> Void)?) throws -> NitroModules.Promise<NitroFile> {
return .async { [unowned self] in
do {
return try await self.nitroFSImpl.downloadFile(
serverUrl: serverUrl,
fileName: fileName,
destinationPath: destinationPath,
onProgress: onProgress
)
Expand Down
25 changes: 10 additions & 15 deletions ios/NitroFSFileDownloader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import Foundation

final class NitroFSFileDownloader: NSObject {
// MARK: - Properties

private weak var fileManager: FileManager?
private var downloadTask: URLSessionDownloadTask?
private var onProgress: ((Double, Double) -> Void)?
Expand All @@ -20,23 +18,20 @@ final class NitroFSFileDownloader: NSObject {
self.fileManager = fileManager
super.init()
}

// MARK: - Public Methods


func downloadFile(
_ serverUrl: String,
_ fileName: String,
_ destinationPath: String,
onProgress: ((Double, Double) -> Void)? = nil
) async throws -> NitroFile {
guard fileManager != nil else {
throw NitroFSError.nitroFSUnavailable(message: "FileManager is not available")
throw NitroFSError.unavailable(message: "FileManager is not available")
}

self.onProgress = onProgress
self.destinationPath = destinationPath

let request = try makeRequest(serverUrl: serverUrl, fileName: fileName)
let request = try makeRequest(serverUrl: serverUrl)

let session: URLSession = {
let config = URLSessionConfiguration.default
Expand All @@ -58,9 +53,9 @@ final class NitroFSFileDownloader: NSObject {

// MARK: - Private Methods

private func makeRequest(serverUrl: String, fileName: String) throws -> URLRequest {
guard let encodedFilename = fileName.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed),
let url = URL(string: "\(serverUrl)/\(encodedFilename)") else {
private func makeRequest(serverUrl: String) throws -> URLRequest {
guard let encoded = serverUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed),
let url = URL(string: encoded) else {
throw URLError(.badURL)
}

Expand All @@ -76,19 +71,19 @@ final class NitroFSFileDownloader: NSObject {
downloadTask: URLSessionDownloadTask
) throws -> NitroFile {
guard let fileManager else {
throw NitroFSError.nitroFSUnavailable(message: "FileManager is not available")
throw NitroFSError.unavailable(message: "FileManager is not available")
}

guard let response = response as? HTTPURLResponse else {
throw NitroFSError.nitroFSDownloadFailed(message: "Invalid response type")
throw NitroFSError.networkError(message: "Invalid response type")
}

guard (200...299).contains(response.statusCode) else {
throw NitroFSError.nitroFSDownloadFailed(message: "HTTP Error: \(response.statusCode)")
throw NitroFSError.networkError(message: "HTTP Error: \(response.statusCode)")
}

guard let destinationPath = self.destinationPath else {
throw NitroFSError.nitroFSDownloadFailed(message: "Destination path not set")
throw NitroFSError.networkError(message: "Destination path not set")
}

let destinationURL = URL(fileURLWithPath: destinationPath)
Expand Down
Loading
Loading