yayan 1 rok temu
rodzic
commit
b53c7c384e

+ 16 - 31
app/src/main/java/io/nexilis/alpha/ui/components/ContentChat.kt

@@ -2,7 +2,6 @@ package io.nexilis.alpha.ui.components
 
 import android.content.Intent
 import android.graphics.BitmapFactory
-import android.net.Uri
 import androidx.compose.foundation.Image
 import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Column
@@ -15,12 +14,10 @@ import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.selection.selectable
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.DownloadForOffline
 import androidx.compose.material.icons.filled.Headset
 import androidx.compose.material.icons.filled.PlayArrow
 import androidx.compose.material3.CircularProgressIndicator
 import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
 import androidx.compose.material3.LinearProgressIndicator
 import androidx.compose.material3.ListItem
 import androidx.compose.material3.ListItemDefaults
@@ -61,6 +58,7 @@ import java.io.FileInputStream
 fun ContentChat(modifier: Modifier = Modifier, message: Message) {
     val context = LocalContext.current
     var selectedItem by remember { mutableStateOf("") }
+    val progressViewModel: ProgressViewModel = hiltViewModel()
     if (message.image_id.isNotEmpty()) {
         Column(modifier = Modifier.padding(2.dp)) {
             val file = File(context.filesDir, message.image_id)
@@ -134,16 +132,21 @@ fun ContentChat(modifier: Modifier = Modifier, message: Message) {
                 .fillMaxWidth(0.76f)
                 .selectable(selected = selectedItem == message.message_id, onClick = {
                     selectedItem = message.message_id
-                    val file = File(context.filesDir, message.file_id)
-                    val uri = FileProvider.getUriForFile(
-                        context, context.applicationContext.packageName + ".provider", file
-                    )
-                    context.startActivity(
-                        Intent(
-                            Intent.ACTION_VIEW,
-                            uri
-                        ).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
-                    )
+                    File(context.filesDir, message.file_id).also {
+                        if (it.exists()) {
+                            val uri = FileProvider.getUriForFile(
+                                context, context.applicationContext.packageName + ".provider", it
+                            )
+                            context.startActivity(
+                                Intent(
+                                    Intent.ACTION_VIEW,
+                                    uri
+                                ).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+                            )
+                        } else {
+                            progressViewModel.download(context, message)
+                        }
+                    }
                 }),
             supportingContent = {
                 FileDesc(file = message.file_id)
@@ -279,7 +282,6 @@ fun FileDesc(file: String, modifier: Modifier = Modifier) {
 
 @Composable
 fun FileProgress(message: Message, modifier: Modifier = Modifier) {
-    val context = LocalContext.current
     val progressViewModel: ProgressViewModel = hiltViewModel()
     val progress by progressViewModel.get(message.message_id).observeAsState()
     progress?.let {
@@ -291,21 +293,4 @@ fun FileProgress(message: Message, modifier: Modifier = Modifier) {
             )
         }
     }
-    val file = File(context.filesDir, message.file_id)
-    if (!file.exists()) {
-        IconButton(
-            onClick = { /*TODO*/ },
-            modifier = modifier
-        ) {
-            Icon(
-                imageVector = Icons.Default.DownloadForOffline,
-                contentDescription = null,
-                tint = Color.LightGray
-            )
-        }
-    }
-}
-
-fun Intent.getActionView(uri: Uri): Intent {
-    return Intent(Intent.ACTION_VIEW, uri).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
 }

+ 54 - 3
cpaas-lite/src/main/java/io/nexilis/service/core/Network.kt

@@ -17,10 +17,14 @@ import okhttp3.RequestBody
 import okhttp3.RequestBody.Companion.asRequestBody
 import okhttp3.RequestBody.Companion.toRequestBody
 import okhttp3.Response
+import okhttp3.ResponseBody
 import okio.Buffer
 import okio.BufferedSink
+import okio.BufferedSource
 import okio.ForwardingSink
+import okio.ForwardingSource
 import okio.Sink
+import okio.Source
 import okio.buffer
 import okio.sink
 import java.io.File
@@ -127,8 +131,25 @@ class Network {
         })
     }
 
-    fun download(context: Context, url: String): Uri? {
-        val client = OkHttpClient()
+    fun download(
+        context: Context,
+        url: String,
+        onProgress: ((Long, Long) -> Unit) = { _, _ -> }
+    ): Uri? {
+        val client = OkHttpClient.Builder()
+            .addNetworkInterceptor {
+                val originalResponse = it.proceed(it.request())
+                val interceptor = originalResponse.newBuilder()
+                    .body(originalResponse.body?.let { it1 ->
+                        ProgressResponseBody(
+                            responseBody = it1,
+                            onProgress = onProgress
+                        )
+                    })
+                    .build()
+                interceptor
+            }
+            .build()
         val request: Request = Request.Builder()
             .url(url)
             .addHeader("User-Agent", "Mozilla/5.0")
@@ -156,6 +177,37 @@ class Network {
 
 }
 
+class ProgressResponseBody(
+    private val responseBody: ResponseBody,
+    private val onProgress: (Long, Long) -> Unit
+) : ResponseBody() {
+    override fun contentType(): MediaType? {
+        return responseBody.contentType()
+    }
+
+    override fun source(): BufferedSource {
+        return ProgressSource(responseBody.source(), onProgress).buffer()
+    }
+
+    override fun contentLength(): Long {
+        return responseBody.contentLength()
+    }
+
+
+    inner class ProgressSource(source: Source, private val onProgress: (Long, Long) -> Unit) :
+        ForwardingSource(source) {
+        private var byteProgress: Long = 0
+
+        override fun read(sink: Buffer, byteCount: Long): Long {
+            val byteRead = super.read(sink, byteCount)
+            byteProgress += if (byteRead != -1L) byteRead else 0
+            onProgress(byteProgress, contentLength())
+            return byteRead
+        }
+    }
+
+}
+
 class ProgressRequestBody(
     private val delegate: RequestBody,
     private val onProgress: (Long, Long) -> Unit
@@ -186,4 +238,3 @@ class ProgressRequestBody(
     }
 
 }
-

+ 0 - 4
cpaas-lite/src/main/java/io/nexilis/service/data/repositories/MessageRepository.kt

@@ -109,10 +109,6 @@ class MessageRepository @Inject constructor(
                             val length = progress.getLong("length", 0)
                             apiScope.launch(Dispatchers.IO) {
                                 messageId?.let {
-                                    Log.d(
-                                        tag,
-                                        "progress from work:$it:$value:$length:${value.toFloat() / length.toFloat()}"
-                                    )
                                     progressDao.upsert(Progress(it, value.toFloat() / length.toFloat()))
                                 }
                             }

+ 18 - 1
cpaas-lite/src/main/java/io/nexilis/service/data/viewmodels/ProgressViewModel.kt

@@ -1,18 +1,35 @@
 package io.nexilis.service.data.viewmodels
 
+import android.content.Context
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
 import dagger.hilt.android.lifecycle.HiltViewModel
+import io.nexilis.service.apiScope
+import io.nexilis.service.core.Network
+import io.nexilis.service.data.entities.Message
 import io.nexilis.service.data.entities.Progress
 import io.nexilis.service.data.repositories.ProgressRepository
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
 import javax.inject.Inject
 
 @HiltViewModel
 class ProgressViewModel @Inject constructor(private val repository: ProgressRepository) :
     ViewModel() {
 
-    fun get(id: String) : LiveData<Progress?> {
+    fun get(id: String): LiveData<Progress?> {
         return repository.get(id)
     }
 
+    fun download(context: Context, message: Message) = apiScope.launch(Dispatchers.IO) {
+        Network().download(
+            context,
+            "https://digixplatform.com/filepalio/image/${message.file_id}"
+        ) { value, length ->
+            viewModelScope.launch(Dispatchers.IO) {
+                repository.upsert(Progress(message.message_id, value.toFloat() / length.toFloat()))
+            }
+        }
+    }
 }