https://kotlinlang.org logo
Title
j

jasu

07/20/2022, 4:11 AM
what’s is proper way to send file upload progress from repository to the compose. I’ve tried sharedFlow, stateFlow nothing seems to be working. One file upload at a time.
f

Filip Wiesner

07/20/2022, 7:39 AM
What do you mean by "sharedFlow, stateFlow nothing seems to be working"? If you have some sort of callback where you receive the progress change, you can use
callbackFlow { ... }
j

jasu

07/20/2022, 7:42 AM
I’m calculating progress in custom request body of retrofit, from there I’m using i’m porting that progress through lambda to the repository, which then puts that progress in a hashMap of particular upload as well as put that map onto the sharedFlow
then I’m collecting that repository upload flow in UI using flow#collectAsState but not all the values from repo are getting received at the UI, only few items are coming rest updates are getting lost in between somehow.
t

Tin Tran

07/20/2022, 7:48 AM
What are you using for the upload process? Using
WorkManager
allow you to query its progress as a
LiveData
which you could then use to collect as state and visualize it on compose
j

jasu

07/20/2022, 7:49 AM
no, I’m posting file directly to the serverUrl using retrofit
f

Filip Wiesner

07/20/2022, 7:49 AM
i’m porting that progress through lambda to the repository
So a callback? If you have some data structure that holds progress for several files that can update independently, then
StateFlow
might be the best option. If you could make the upload function like
fun uploadFile(path: String): Flow<Progress>
, then I would use
callbackFlow { ... }
I've never worked with Retrofit extensively so I don't know how this works but if the question is just "_what’s is proper way to send file upload progress from repository to the compose_", then the answer for me is
flow { ... }
or
callbackFlow { ... }
.
j

jasu

07/20/2022, 7:52 AM
I tried using callbackFlow, it was causing some other issues(abruptly closing channel) then I used lambda directly.
alright man, thanks
f

Filip Wiesner

07/20/2022, 7:57 AM
Sorry, I don't know how to help you more than this 😅 Good luck
🤗 1
t

Tin Tran

07/20/2022, 8:03 AM
fun ResponseBody?.writeToFileWithProgress(file: File?): Flow<Int> {
    if (this == null || file == null) {
        this?.close()
        return emptyFlow()
    }
    val body = this
    return flow {
        body.use {
            body.byteStream().use { inStream ->
                val outStream = file.outputStream()
                outStream.use {
                    var read: Int
                    val buffer = ByteArray(Constants.BUFFER_SIZE)
                    while (inStream.read(buffer).also { read = it } != -1) {
                        emit(read)
                        outStream.write(buffer, 0, read)
                    }
                }
            }
        }
    }
}
I’m using this for download but for upload it’s pretty much the same. It’s woking well in my production app
j

jasu

07/20/2022, 10:13 AM
oh okay, let me check. Thanks dude