yayan пре 1 година
родитељ
комит
8426d71bd4

+ 1 - 2
app/src/main/java/io/nexilis/alpha/ui/components/Attachments.kt

@@ -107,8 +107,7 @@ fun Attachments(modifier: Modifier, onAttachment: (List<Uri>) -> Unit) {
             Box(modifier = modifier) {
                 Row(Modifier.align(Alignment.Center)) {
                     var mimeType = arrayOf(
-                        "doc/*",
-                        "docx/*",
+                        "text/*",
                         "application/*"
                     )
                     val launcherFiles =

+ 72 - 23
app/src/main/java/io/nexilis/alpha/ui/components/ContentChat.kt

@@ -11,10 +11,11 @@ import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.InsertDriveFile
+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.Icon
+import androidx.compose.material3.IconButton
 import androidx.compose.material3.LinearProgressIndicator
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
@@ -23,15 +24,21 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.vectorResource
+import androidx.compose.ui.text.intl.Locale
 import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.text.toUpperCase
 import androidx.compose.ui.unit.dp
 import androidx.core.content.FileProvider
 import coil.compose.rememberAsyncImagePainter
 import io.nexilis.alpha.BuildConfig
-import io.nexilis.service.core.DarkLimeGreen
+import io.nexilis.alpha.R
 import io.nexilis.service.core.Orange
+import io.nexilis.service.core.extension
+import io.nexilis.service.core.toHumanStandard
 import io.nexilis.service.data.entities.Message
 import java.io.File
 
@@ -68,30 +75,24 @@ fun ContentChat(modifier: Modifier, message: Message) {
         Column(
             modifier = Modifier
                 .padding(2.dp)
-                .widthIn(max = 210.dp)
+                .fillMaxWidth(0.65f)
         ) {
             Row(modifier = Modifier
                 .graphicsLayer {
                     shape = RoundedCornerShape(12.dp)
                     clip = true
                 }
-                .background(MaterialTheme.colorScheme.surface)) {
-                Icon(
-                    modifier = Modifier
-                        .size(48.dp)
-                        .padding(start = 8.dp)
-                        .align(Alignment.CenterVertically),
-                    imageVector = Icons.AutoMirrored.Filled.InsertDriveFile,
-                    contentDescription = null,
-                    tint = Color.DarkLimeGreen
+                .align(Alignment.CenterHorizontally)
+                .background(MaterialTheme.colorScheme.surface)
+                .padding(8.dp)
+            ) {
+                FileType(
+                    file = message.file_id, modifier = Modifier
+                        .align(Alignment.CenterVertically)
                 )
                 Column(
-                    modifier = Modifier.padding(
-                        start = 4.dp,
-                        top = 8.dp,
-                        end = 8.dp,
-                        bottom = 8.dp
-                    )
+                    modifier = Modifier
+                        .weight(1f)
                 ) {
                     Text(
                         text = message.message_text.split("|").first(),
@@ -100,11 +101,20 @@ fun ContentChat(modifier: Modifier, message: Message) {
                         maxLines = 2,
                         overflow = TextOverflow.Ellipsis
                     )
-                    Text(
-                        text = "11 KB • XLSX",
-                        color = MaterialTheme.colorScheme.onSurface,
-                        style = MaterialTheme.typography.labelSmall,
-                    )
+                    FileDesc(file = message.file_id)
+                }
+                val file = File(context.filesDir, message.file_id)
+                if (!file.exists()) {
+                    IconButton(
+                        onClick = { /*TODO*/ },
+                        modifier = Modifier.align(Alignment.CenterVertically)
+                    ) {
+                        Icon(
+                            imageVector = Icons.Default.DownloadForOffline,
+                            contentDescription = null,
+                            tint = Color.LightGray
+                        )
+                    }
                 }
             }
             val messageText = message.message_text.split("|").last()
@@ -195,4 +205,43 @@ fun ContentChat(modifier: Modifier, message: Message) {
             style = MaterialTheme.typography.bodyMedium,
         )
     }
+}
+
+@Composable
+fun FileType(file: String, modifier: Modifier) {
+    val imageVector = when (file.extension) {
+        "apk", "aab" -> ImageVector.vectorResource(id = R.drawable.ic_apk)
+        "aac", "mp3", "m4a", "ogg" -> ImageVector.vectorResource(id = R.drawable.ic_audio)
+        "xls", "xlsx" -> ImageVector.vectorResource(id = R.drawable.ic_excel)
+        "jpg", "jpeg", "webp", "png", "svg" -> ImageVector.vectorResource(id = R.drawable.ic_image)
+        "pdf" -> ImageVector.vectorResource(id = R.drawable.ic_pdf)
+        "ppt", "pptx" -> ImageVector.vectorResource(id = R.drawable.ic_ppt)
+        "txt" -> ImageVector.vectorResource(id = R.drawable.ic_txt)
+        "mp4", "mov", "3gp" -> ImageVector.vectorResource(id = R.drawable.ic_video)
+        "doc", "docx" -> ImageVector.vectorResource(id = R.drawable.ic_word)
+        "zip", "gz", "rar" -> ImageVector.vectorResource(id = R.drawable.ic_zip)
+        else -> ImageVector.vectorResource(id = R.drawable.ic_file)
+    }
+    Image(
+        modifier = modifier
+            .size(48.dp),
+        imageVector = imageVector,
+        contentDescription = null
+    )
+}
+
+@Composable
+fun FileDesc(file: String, modifier: Modifier = Modifier) {
+    val context = LocalContext.current
+    val f = File(context.filesDir, file)
+    if (f.exists()) {
+        Text(
+            modifier = modifier,
+            text = "${
+                f.length().toHumanStandard()
+            } • ${file.extension.toUpperCase(Locale.current)}",
+            color = MaterialTheme.colorScheme.onSurface,
+            style = MaterialTheme.typography.labelSmall,
+        )
+    }
 }

Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_apk.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_audio.xml


Разлика између датотеке није приказан због своје велике величине
+ 7 - 0
app/src/main/res/drawable/ic_excel.xml


Разлика између датотеке није приказан због своје велике величине
+ 7 - 0
app/src/main/res/drawable/ic_file.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_image.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_pdf.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_ppt.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_txt.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_video.xml


Разлика између датотеке није приказан због своје велике величине
+ 7 - 0
app/src/main/res/drawable/ic_word.xml


Разлика између датотеке није приказан због своје велике величине
+ 6 - 0
app/src/main/res/drawable/ic_zip.xml


+ 21 - 0
cpaas-lite/src/main/java/io/nexilis/service/core/ChatNotification.kt

@@ -57,4 +57,25 @@ class ChatNotification(private val context: Context) {
         }
         return builder.build()
     }
+
+    fun getNotification(
+        title: String,
+        text: String,
+        style: NotificationCompat.Style
+    ): Notification {
+        val channelId = context.getString(R.string.notification_chat_channel_id)
+        val name = context.getString(R.string.channel_name_chat)
+        val builder = NotificationCompat.Builder(context, channelId)
+            .setContentTitle(title)
+            .setContentText(text)
+            .setSmallIcon(context.applicationInfo.icon)
+            .setStyle(style)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            createNotificationChannel(channelId, name).also {
+                builder.setChannelId(it.id)
+            }
+        }
+        return builder.build()
+    }
+
 }

+ 18 - 0
cpaas-lite/src/main/java/io/nexilis/service/core/Extension.kt

@@ -17,7 +17,9 @@ import java.net.URLEncoder
 import java.nio.charset.StandardCharsets
 import java.security.MessageDigest
 import java.security.SecureRandom
+import java.text.CharacterIterator
 import java.text.SimpleDateFormat
+import java.text.StringCharacterIterator
 import java.util.Date
 import java.util.Locale
 
@@ -87,6 +89,9 @@ fun Context.getMimeType(uri: Uri): String {
     return ""
 }
 
+val String.extension: String
+    get() = this.substringAfterLast('.', "")
+
 fun String.toMD5(): String {
     val md = MessageDigest.getInstance("MD5")
     val hashInBytes = md.digest(this.toByteArray(StandardCharsets.UTF_8))
@@ -149,6 +154,19 @@ val Color.Companion.DarkLimeGreen: Color
 val Color.Companion.BlueSky: Color
     get() = Color(0xFF0075F1)
 
+fun Long.toHumanStandard(): String {
+    var b = this
+    if (-1000 < b && b < 1000) {
+        return "$b B"
+    }
+    val ci: CharacterIterator = StringCharacterIterator("kMGTPE")
+    while (b <= -999950 || b >= 999950) {
+        b /= 1000
+        ci.next()
+    }
+    return String.format("%.1f %cB", b / 1000.0, ci.current())
+}
+
 class Secret {
     private val iBB = 48 // 0
 

Неке датотеке нису приказане због велике количине промена