From 97338f20d1bb647b24e2e6ac4333faf0e06b2e56 Mon Sep 17 00:00:00 2001 From: Juha Heinanen Date: Thu, 27 Nov 2025 10:32:31 +0200 Subject: [PATCH] Work on notification improvements --- .../com/tutpro/baresip/BaresipService.kt | 139 +++++++++++++----- .../main/kotlin/com/tutpro/baresip/Contact.kt | 10 ++ .../main/kotlin/com/tutpro/baresip/Utils.kt | 66 ++++++++- app/src/main/res/drawable-hdpi/ic_stat.png | Bin 408 -> 0 bytes .../main/res/drawable-hdpi/ic_stat_call.png | Bin 595 -> 0 bytes .../res/drawable-hdpi/ic_stat_call_end.png | Bin 422 -> 0 bytes .../res/drawable-hdpi/ic_stat_call_missed.png | Bin 629 -> 0 bytes .../main/res/drawable-hdpi/ic_stat_delete.png | Bin 309 -> 0 bytes .../res/drawable-hdpi/ic_stat_message.png | Bin 362 -> 0 bytes .../main/res/drawable-hdpi/ic_stat_reply.png | Bin 531 -> 0 bytes .../main/res/drawable-hdpi/ic_stat_save.png | Bin 513 -> 0 bytes app/src/main/res/drawable-mdpi/ic_stat.png | Bin 294 -> 0 bytes .../main/res/drawable-mdpi/ic_stat_call.png | Bin 342 -> 0 bytes .../res/drawable-mdpi/ic_stat_call_end.png | Bin 351 -> 0 bytes .../res/drawable-mdpi/ic_stat_call_missed.png | Bin 492 -> 0 bytes .../main/res/drawable-mdpi/ic_stat_delete.png | Bin 198 -> 0 bytes .../res/drawable-mdpi/ic_stat_message.png | Bin 248 -> 0 bytes .../main/res/drawable-mdpi/ic_stat_reply.png | Bin 331 -> 0 bytes .../main/res/drawable-mdpi/ic_stat_save.png | Bin 286 -> 0 bytes app/src/main/res/drawable-xhdpi/ic_stat.png | Bin 533 -> 0 bytes .../main/res/drawable-xhdpi/ic_stat_call.png | Bin 680 -> 0 bytes .../res/drawable-xhdpi/ic_stat_call_end.png | Bin 592 -> 0 bytes .../drawable-xhdpi/ic_stat_call_missed.png | Bin 961 -> 0 bytes .../res/drawable-xhdpi/ic_stat_delete.png | Bin 274 -> 0 bytes .../res/drawable-xhdpi/ic_stat_message.png | Bin 332 -> 0 bytes .../main/res/drawable-xhdpi/ic_stat_reply.png | Bin 599 -> 0 bytes .../main/res/drawable-xhdpi/ic_stat_save.png | Bin 528 -> 0 bytes app/src/main/res/drawable-xxhdpi/ic_stat.png | Bin 785 -> 0 bytes .../main/res/drawable-xxhdpi/ic_stat_call.png | Bin 1227 -> 0 bytes .../res/drawable-xxhdpi/ic_stat_call_end.png | Bin 780 -> 0 bytes .../drawable-xxhdpi/ic_stat_call_missed.png | Bin 1239 -> 0 bytes .../res/drawable-xxhdpi/ic_stat_delete.png | Bin 495 -> 0 bytes .../res/drawable-xxhdpi/ic_stat_message.png | Bin 587 -> 0 bytes .../res/drawable-xxhdpi/ic_stat_reply.png | Bin 1071 -> 0 bytes .../main/res/drawable-xxhdpi/ic_stat_save.png | Bin 924 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_call.png | Bin 1356 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_call_end.png | Bin 1212 -> 0 bytes .../drawable-xxxhdpi/ic_stat_call_missed.png | Bin 1957 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_delete.png | Bin 547 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_message.png | Bin 592 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_reply.png | Bin 1231 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_save.png | Bin 1028 -> 0 bytes .../main/res/drawable/ic_notification_b.xml | 9 ++ .../res/drawable/ic_notification_call.xml | 9 ++ .../res/drawable/ic_notification_call_end.xml | 9 ++ .../drawable/ic_notification_call_missed.xml | 10 ++ .../res/drawable/ic_notification_delete.xml | 9 ++ .../res/drawable/ic_notification_message.xml | 10 ++ .../res/drawable/ic_notification_reply.xml | 9 ++ .../res/drawable/ic_notification_save.xml | 9 ++ app/src/main/res/values-fi/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + gradle/libs.versions.toml | 1 + 53 files changed, 253 insertions(+), 39 deletions(-) delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_call.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_call_end.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_call_missed.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_delete.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_message.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_reply.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_save.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_call.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_call_end.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_call_missed.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_delete.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_message.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_reply.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_save.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_call.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_call_end.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_call_missed.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_delete.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_message.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_reply.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_save.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_call.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_call_end.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_call_missed.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_delete.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_message.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_reply.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_save.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_call.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_call_end.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_call_missed.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_delete.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_message.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_reply.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_save.png create mode 100644 app/src/main/res/drawable/ic_notification_b.xml create mode 100644 app/src/main/res/drawable/ic_notification_call.xml create mode 100644 app/src/main/res/drawable/ic_notification_call_end.xml create mode 100644 app/src/main/res/drawable/ic_notification_call_missed.xml create mode 100644 app/src/main/res/drawable/ic_notification_delete.xml create mode 100644 app/src/main/res/drawable/ic_notification_message.xml create mode 100644 app/src/main/res/drawable/ic_notification_reply.xml create mode 100644 app/src/main/res/drawable/ic_notification_save.xml diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 01e71248..64f4333d 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -20,11 +20,12 @@ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_PHONE_CALL import android.content.res.Configuration import android.database.ContentObserver +import android.graphics.ImageDecoder +import android.media.AudioAttributes import android.media.AudioDeviceInfo import android.media.AudioManager import android.media.AudioManager.MODE_IN_COMMUNICATION import android.media.AudioManager.MODE_NORMAL -import android.media.AudioManager.RINGER_MODE_SILENT import android.media.MediaPlayer import android.media.Ringtone import android.media.RingtoneManager @@ -65,11 +66,13 @@ import androidx.core.app.NotificationCompat.MessagingStyle import androidx.core.app.Person import androidx.core.app.RemoteInput import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.IconCompat import androidx.core.net.toUri import androidx.lifecycle.MutableLiveData import androidx.media.AudioAttributesCompat import androidx.media.AudioFocusRequestCompat import androidx.media.AudioManagerCompat +import com.tutpro.baresip.Utils.toCircle import java.io.File import java.net.InetAddress import java.nio.charset.Charset @@ -885,7 +888,7 @@ class BaresipService: Service() { startActivity(newIntent) return } - val channelId = if (shouldVibrate()) MEDIUM_CHANNEL_ID else HIGH_CHANNEL_ID + val channelId = if (shouldVibrate()) HIGH_CHANNEL_ID else MEDIUM_CHANNEL_ID val callerNumber = peerUri.split(":")[1].split("@")[0] if (shouldStartRinging(channelId, callerNumber)) startRinging() @@ -899,15 +902,40 @@ class BaresipService: Service() { val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, intent, piFlags) val nb = NotificationCompat.Builder(this, channelId) val caller = Utils.friendlyUri(this, peerUri, ua.account) - val person = Person.Builder().setName(caller).build() - nb.setSmallIcon(R.drawable.ic_stat_call) + val callerContact = Contact.findContact(peerUri) + val personBuilder = Person.Builder().setName(caller) + val contactColor = callerContact?.color() ?: "#B0B0B0" + val initial = if (caller.isNotEmpty()) caller.take(1) else "?" + val textAvatarBitmap = Utils.createTextAvatar(this, initial,contactColor) + var icon = IconCompat.createWithBitmap(textAvatarBitmap) + if (callerContact is Contact.BaresipContact) { + if (callerContact.avatarImage != null) + icon = IconCompat.createWithBitmap(callerContact.avatarImage!!.toCircle()) + } + else if (callerContact is Contact.AndroidContact) { + // AndroidContact has a URI, we must decode it + if (callerContact.thumbnailUri != null) { + try { + val source = ImageDecoder.createSource(contentResolver, + callerContact.thumbnailUri!!) + val bitmap = ImageDecoder.decodeBitmap(source) { decoder, _, _ -> + decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE + // decoder.setTargetSize(256, 256) + } + icon = IconCompat.createWithBitmap(bitmap.toCircle()) + } catch (e: Exception) { + Log.e(TAG, "Failed to load Android contact avatar: $e") + } + } + } + val person = personBuilder.setIcon(icon).build() + nb.setSmallIcon(R.drawable.ic_notification_call) .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) .setContentIntent(pi) .setCategory(Notification.CATEGORY_CALL) .setAutoCancel(false) .setOngoing(true) - .setContentTitle(getString(R.string.incoming_call_from)) - .setContentText(caller) + .setContentText(getString(R.string.is_calling)) .setWhen(System.currentTimeMillis()) .setShowWhen(true) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) @@ -985,7 +1013,7 @@ class BaresipService: Service() { val pi = PendingIntent.getActivity(applicationContext, TRANSFER_REQ_CODE, intent, piFlags) val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) val target = Utils.friendlyUri(this, ev[1], ua.account) - nb.setSmallIcon(R.drawable.ic_stat_call) + nb.setSmallIcon(R.drawable.ic_notification_call) .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) .setContentIntent(pi) .setDefaults(Notification.DEFAULT_SOUND) @@ -1004,8 +1032,10 @@ class BaresipService: Service() { denyIntent.putExtra("callp", callp) val denyPendingIntent = PendingIntent.getService(this, DENY_REQ_CODE, denyIntent, piFlags) - nb.addAction(R.drawable.ic_stat_call, getString(R.string.accept), acceptPendingIntent) - nb.addAction(R.drawable.ic_stat_call_end, getString(R.string.deny), denyPendingIntent) + nb.addAction(R.drawable.ic_notification_call, + getString(R.string.accept), acceptPendingIntent) + nb.addAction(R.drawable.ic_notification_call_end, + getString(R.string.deny), denyPendingIntent) nm.notify(TRANSFER_NOTIFICATION_ID, nb.build()) return } @@ -1082,7 +1112,7 @@ class BaresipService: Service() { val pi = PendingIntent.getActivity(applicationContext, CALL_REQ_CODE, intent, piFlags) val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) - nb.setSmallIcon(R.drawable.ic_stat_call_missed) + nb.setSmallIcon(R.drawable.ic_notification_call_missed) .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) .setContentIntent(pi) .setCategory(Notification.CATEGORY_CALL) @@ -1167,11 +1197,34 @@ class BaresipService: Service() { val pi = PendingIntent.getActivity(applicationContext, MESSAGE_REQ_CODE, intent, piFlags) // message notification builder - val senderDisplayName = Utils.friendlyUri(this, peerUri, ua.account) - val senderPerson = Person.Builder() - .setName(senderDisplayName) - .setKey(peerUri) - .build() + val sender = Utils.friendlyUri(this, peerUri, ua.account) + val senderContact = Contact.findContact(peerUri) + val personBuilder = Person.Builder().setName(sender) + val contactColor = senderContact?.color() ?: "#B0B0B0" + val initial = if (sender.isNotEmpty()) sender.take(1) else "?" + val textAvatarBitmap = Utils.createTextAvatar(this, initial,contactColor) + var icon = IconCompat.createWithBitmap(textAvatarBitmap) + if (senderContact is Contact.BaresipContact) { + if (senderContact.avatarImage != null) + icon = IconCompat.createWithBitmap(senderContact.avatarImage!!.toCircle()) + } + else if (senderContact is Contact.AndroidContact) { + // AndroidContact has a URI, we must decode it + if (senderContact.thumbnailUri != null) { + try { + val source = ImageDecoder.createSource(contentResolver, + senderContact.thumbnailUri!!) + val bitmap = ImageDecoder.decodeBitmap(source) { decoder, _, _ -> + decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE + // decoder.setTargetSize(256, 256) + } + icon = IconCompat.createWithBitmap(bitmap.toCircle()) + } catch (e: Exception) { + Log.e(TAG, "Failed to load Android contact avatar: $e") + } + } + } + val senderPerson = personBuilder.setIcon(icon).build() val localUserPerson = Person.Builder() .setName(getString(R.string.you)) .setKey(ua.account.aor) @@ -1181,7 +1234,7 @@ class BaresipService: Service() { .setGroupConversation(false) .addMessage(text, timeStamp, senderPerson) val nb = NotificationCompat.Builder(this, HIGH_CHANNEL_ID) - .setSmallIcon(R.drawable.ic_stat_message) + .setSmallIcon(R.drawable.ic_notification_message) .setColor(ContextCompat.getColor(this, R.color.colorPrimary)) .setContentIntent(pi) .setSound(Settings.System.DEFAULT_NOTIFICATION_URI) @@ -1190,7 +1243,7 @@ class BaresipService: Service() { .setCategory(NotificationCompat.CATEGORY_MESSAGE) .setPriority(NotificationCompat.PRIORITY_HIGH) - // messafe inline reply + // message inline reply val remoteInput = RemoteInput.Builder(KEY_TEXT_REPLY) .setLabel(getString(R.string.reply)) .build() @@ -1204,7 +1257,7 @@ class BaresipService: Service() { PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE ) val inlineReplyAction = NotificationCompat.Action.Builder( - R.drawable.ic_stat_reply, + R.drawable.ic_notification_reply, getString(R.string.reply), directReplyPendingIntent ).addRemoteInput(remoteInput) @@ -1218,7 +1271,7 @@ class BaresipService: Service() { saveIntent.putExtra("uap", uap).putExtra("time", timeStampString) val savePendingIntent = PendingIntent.getService(this, SAVE_REQ_CODE, saveIntent, piFlags) val saveAction = NotificationCompat.Action.Builder( - R.drawable.ic_stat_save, + R.drawable.ic_notification_save, getString(R.string.save), savePendingIntent ).build() @@ -1229,7 +1282,7 @@ class BaresipService: Service() { deleteIntent.putExtra("uap", uap).putExtra("time", timeStampString) val deletePendingIntent = PendingIntent.getService(this, DELETE_REQ_CODE, deleteIntent, piFlags) val deleteAction = NotificationCompat.Action.Builder( - R.drawable.ic_stat_delete, + R.drawable.ic_notification_delete, getString(R.string.delete), deletePendingIntent ).build() @@ -1294,22 +1347,29 @@ class BaresipService: Service() { } private fun createNotificationChannels() { - val lowChannel = NotificationChannel(LOW_CHANNEL_ID, "No sound or vibrate", + val lowChannel = NotificationChannel(LOW_CHANNEL_ID, "No sound, no vibrate", NotificationManager.IMPORTANCE_LOW) + lowChannel.description = "Background status notifications" lowChannel.enableVibration(false) lowChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC nm.createNotificationChannel(lowChannel) - - val highChannel = NotificationChannel(HIGH_CHANNEL_ID, "Sound and vibrate", + val ringAttributes = AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE) + .build() + val highChannel = NotificationChannel(HIGH_CHANNEL_ID, "Sound, vibrate, and peek", NotificationManager.IMPORTANCE_HIGH) + highChannel.description = "Incoming calls and important alerts" highChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC highChannel.enableVibration(true) + highChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, ringAttributes) nm.createNotificationChannel(highChannel) - - val mediumChannel = NotificationChannel(MEDIUM_CHANNEL_ID, "Sound", - NotificationManager.IMPORTANCE_HIGH) + val mediumChannel = NotificationChannel(MEDIUM_CHANNEL_ID, "Sound only", + NotificationManager.IMPORTANCE_DEFAULT) + mediumChannel.description = "Incoming messages" mediumChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC mediumChannel.enableVibration(false) + mediumChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI, ringAttributes) nm.createNotificationChannel(mediumChannel) } @@ -1322,7 +1382,7 @@ class BaresipService: Service() { PendingIntent.FLAG_IMMUTABLE) val notificationLayout = RemoteViews(packageName, R.layout.status_notification) snb.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setSmallIcon(R.drawable.ic_stat) + .setSmallIcon(R.drawable.ic_notification_b) .setContentIntent(pi) .setOngoing(true) .setStyle(NotificationCompat.DecoratedCustomViewStyle()) @@ -1413,17 +1473,22 @@ class BaresipService: Service() { } private fun shouldVibrate(): Boolean { - return if (am.ringerMode != RINGER_MODE_SILENT) - if (am.ringerMode == AudioManager.RINGER_MODE_VIBRATE) - true - else - if (am.getStreamVolume(AudioManager.STREAM_RING) != 0) - @Suppress("DEPRECATION") - Settings.System.getInt(contentResolver, Settings.System.VIBRATE_WHEN_RINGING, 0) != 0 - else - false - else + // 1. If the phone is in Silent mode, never vibrate + if (am.ringerMode == AudioManager.RINGER_MODE_SILENT) return false + // 2. If the phone is in Vibrate mode, always vibrate + if (am.ringerMode == AudioManager.RINGER_MODE_VIBRATE) return true + // 3. If the phone is in Normal (Ringing) mode: + // First, check if the ringer volume is actually non-zero + if (am.getStreamVolume(AudioManager.STREAM_RING) == 0) return false + // Finally, check the system "Vibrate for calls" setting. + // Although deprecated, it is the standard way to check the "Also vibrate for calls" toggle. + return try { + @Suppress("DEPRECATION") + Settings.System.getInt(contentResolver, Settings.System.VIBRATE_WHEN_RINGING, 0) != 0 + } catch (_: Exception) { + // If the setting can't be read, default to FALSE to be non-intrusive. false + } } private fun isStarredContact(callerNumber: String): Boolean { diff --git a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt index b34bd686..0d8f398c 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Contact.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Contact.kt @@ -44,6 +44,16 @@ sealed class Contact { } } + fun color(): String { + val intColor = when (this) { + is AndroidContact -> color + is BaresipContact -> color + } + // Mask with 0xFFFFFF to ensure we get the standard 6-character hex code (RRGGBB) + // ignoring the alpha channel for compatibility with simple string parsers. + return String.format("#%06X", 0xFFFFFF and intColor) + } + fun copy(): Contact { val copy = when (this) { is BaresipContact -> diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 5028ddf9..fa0f2c4e 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -8,6 +8,9 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.content.res.Configuration +import android.graphics.Bitmap +import android.graphics.PorterDuff +import android.graphics.PorterDuffXfermode import android.media.AudioAttributes import android.media.AudioDeviceInfo import android.media.AudioManager @@ -71,7 +74,7 @@ import javax.net.ssl.HttpsURLConnection import javax.net.ssl.SSLContext import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager -import kotlin.text.replaceFirstChar +import androidx.core.graphics.toColorInt object Utils { @@ -169,7 +172,7 @@ object Utils { private fun e164Uri(uri: String, countryCode: String): String { if (countryCode == "") return uri - val scheme = uri.substring(0, 4) + val scheme = uri.take(4) val userPart = uriUserPart(uri) return if (userPart.isDigitsOnly()) { when { @@ -1083,6 +1086,65 @@ object Utils { } } + fun Bitmap.toCircle(): Bitmap { + // Use full package names to avoid conflict with Compose classes + val output = androidx.core.graphics.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888) + val canvas = android.graphics.Canvas(output) + val paint = android.graphics.Paint() + val rect = android.graphics.Rect(0, 0, this.width, this.height) + + paint.isAntiAlias = true + canvas.drawARGB(0, 0, 0, 0) + + canvas.drawCircle(this.width / 2f, this.height / 2f, this.width / 2f, paint) + + paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) + canvas.drawBitmap(this, rect, rect, paint) + return output + } + + fun createTextAvatar(context: Context, letter: String, colorHex: String): Bitmap { + // Standard notification large icon size is usually 64dp or 48dp. + // We use a decent resolution (e.g. 128x128) and let Android scale it down. + val size = 128 + + // Use KTX createBitmap to match toCircle style + val bitmap = androidx.core.graphics.createBitmap(size, size, Bitmap.Config.ARGB_8888) + + // Use Fully Qualified Names to avoid Compose conflicts + val canvas = android.graphics.Canvas(bitmap) + + // 1. Draw the colored circle background + val bgPaint = android.graphics.Paint() + bgPaint.isAntiAlias = true + try { + bgPaint.color = colorHex.toColorInt() + } catch (_: Exception) { + bgPaint.color = android.graphics.Color.GRAY // Fallback color + } + canvas.drawCircle(size / 2f, size / 2f, size / 2f, bgPaint) + + // 2. Draw the text (Initial) + val textPaint = android.graphics.Paint() + textPaint.isAntiAlias = true + textPaint.color = android.graphics.Color.WHITE + textPaint.textSize = size / 2f // Text size is half the circle size + textPaint.textAlign = android.graphics.Paint.Align.CENTER + + // Use a bold font if possible to match your UI + textPaint.typeface = android.graphics.Typeface.create(android.graphics.Typeface.DEFAULT, android.graphics.Typeface.BOLD) + + // Calculate vertical center to center the text properly + val bounds = android.graphics.Rect() + textPaint.getTextBounds(letter, 0, letter.length, bounds) + val yOffset = (bounds.bottom - bounds.top) / 2f + + // Draw text at Center X, Center Y + half text height (to visually center) + canvas.drawText(letter.uppercase(), size / 2f, (size / 2f) + (yOffset / 2) + (bounds.height()/4), textPaint) + + return bitmap + } + /*fun listFilesInDirectory(directoryPath: String): List { val directory = File(directoryPath) if (!directory.exists()) { diff --git a/app/src/main/res/drawable-hdpi/ic_stat.png b/app/src/main/res/drawable-hdpi/ic_stat.png deleted file mode 100644 index 4cb8bdfba22025e00e11afc132db7f6e26fdb06b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 408 zcmV;J0cZY+P)BL466nu0-u+YjvL9i69 z1QBd36d&ukFvW1$*kx{zxp3IsnGg1`>^zuECf0weBuNIL3|mlxT{wnIC|C$hCyi^= zLZ|>$IDj8>AtiU!YC>mGC<;X(DGt(w4<_BYoUtD z-dYQ7s_Z-DEQK~wMr7VnsFWf!)@ni{mO|?)D?`7}QmCx5GGn(}3e{Bh(0bU{Rdzmv z&}xHR4&KzN-x)&aIc;vCZOzMk!%T?9^%P#=4klfH7M9?{8(AwM_Cx2;1yk_oUM$xa zPgtId&E7H2xi8S~wROV+Y`guDoC6d^IG!CfqkaJzYD9&prIrc+0000SeER8lY% zT#brJKm+((2bvKoa8(hYHe62u9mn$Mpaiu$C5PT%V^N?sTuI5J(Lz88st?n3sCo1h z1!~6$%+<}(7pyA^)sM$1OZNg>iU74^KVH?Leqanci$Ild81L$4X*xlbi$L|@T#`Sv zs0yB8puzYXcrG*wBN)Q^zeRQ9a!NkU<2`m{j2jj<)~eswIkfu8&^q6{_+gMupcpPldf_Jo!A2-ll_6fXlF2c>S{- hyM+8(5gn5^egY(~VdkTYnd|@n002ovPDHLkV1n8U1VsP< diff --git a/app/src/main/res/drawable-hdpi/ic_stat_call_end.png b/app/src/main/res/drawable-hdpi/ic_stat_call_end.png deleted file mode 100644 index 5bcc20b603002a465d6e0a34945315e3649c5148..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 422 zcmV;X0a^ZuP) zF-u!v6vlChanM3b72Fhx$v zpy1GJ>7GFMa-ahn{Ir>8R{)Q@&~`Li;Ym9agM(& z&ey}cPbhT~Jc44NliCRYMEBSkT?YW!bRl^RR zwh|R2Q}QiC+>byFeqa`bv}j&39qs5xAd+8UJ}p|pzZ}B-E&}c3@P(zcsEp$rqO~pp zz0cwMUGu(@Y~DRLJ5`sA_j0FUQr?UB>E`;V<51RSM+sk2f*L;PWN&1LDq~%;zZz7u znzAP0Lmc5ZRxxzjFe&dM-UaWkc$8N-h8NPK*t<}L;62`J??@yPiQG&61DHmT+gV+T Q^8f$<07*qoM6N<$f|0PHyhh)Kpc~|0XQQ z)`VDHhDSYSrv-FgvaTbOP@lzqyu_mE0J@9Yu{c%=2#x4N4j<8#CeT=TJ&M{g>M|iW zk6~<_GE4!`&9KTGPM|TNrUA!8?g(}un>NrvEWzh+eX>}m!p!uBoG)0F3P>@aaJ@6u zsb18_a_eyj-@^O5k_J94pbS=q)#q^vb*K$rQyyQ@kvdEO=)-I5E4aT6L->v(I1oBB zjNPeGwQZJ1SXKZ~^iVl+e!8&VtK$te7ShC*k$XAC3;REOXGD8TF+Hwmb&=;l5uY)< z5uFBFOBFWYK?#twf#P8O3TI37-}H0>nCSo-*DI`u7xnma0GkOQ=!q9~;%ym4S0@2< zp^U|TKxbj$Vholj7{xiXOaiD`w2|gYc)!EaQpH`Or-O0j@erFT1u5da2KVtZ=0Awd zNkthfi*@QU=1dhP=HG@(!TY`FnQ!7l9Oh!ZX*kz}MX$qxw7sjU>Yvnaj}Kp@y>{&2 P00000NkvXXu0mjfsahL~ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_delete.png b/app/src/main/res/drawable-hdpi/ic_stat_delete.png deleted file mode 100644 index 08df7d8e99744d6da10c9b8fc2e1bcd1eb9e6da6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 309 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB{&>1LhD5Z!y{_x+9LR9|A*Y`s zOJdU8MRyBWo0|gnH%G8@Ydd#8I4J0sx2qvsoTKDeEH;}EZO`SXhPP4n#k zyt4GSe0U|RJ~6^6?7}Di#A}6}vzyj!2)wq`_YF^``1OkLJ^pu+^N&QH6$p^lcYgIS zna4-&s&rwPHOm#w9VTUS1p>Iwi(cnqOto0CBPS<-@7jT+lV_8a*o<3i|AvRAwa@5f z^nL8|)B11>lWG7Gx?s;J8_rg-d{|&d~yLEdQeU`8S!-2um)z4*}Q$iB}y$5`z diff --git a/app/src/main/res/drawable-hdpi/ic_stat_message.png b/app/src/main/res/drawable-hdpi/ic_stat_message.png deleted file mode 100644 index f6822daa2e812ceeff0e6712dd11bc8f9263c2c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 362 zcmV-w0hRuVP)$`tC=jl18r6tcn8~RafQU_4@2-AZNoTH4(2Dgk0?4Y;a$!y?R^Yemz z)h8vprn3Z?w_IVU8Z;t1!c@7zST(39yVq2?#rUrUZDS^=n-QRy?{Btut7Ym>g7&Zw z)U60m1@}RHiU6%)GN{WDpxn(+?m$N<1@#~TbSL{JMD!*Cw1nZHE=GWIH$!tM1a&$B zbRv6TBYGSGYDWG+pXC~(c>?mk)OAdtvvy&91SXP)?GP66+}d|Gm3(hmO?rU3yT!C zVr8e5C?1|U(0Hhi#mt#YIOFc#Z5HI-eqSDDX6KtE>8GEPg6(A+k|aqIRB#Jt%C;mJ z!VP@Kxw0`MxQ4or@<15JEIwLJIiQHSjQ3V%{Xub?W;*4 zRB*lR0C!3qZ}A%QxP<-KSOn%~{I%2M7k*$VBA?-SuP}pgWzu5S%1caPFfV2VSMa$9 zm{t~r)!vN_Suk5LgAYB#wDL_jV+W-@UlVfX|D-k zujk^&MPvz&Fq#S!Q4879 V<$S3tgGB%U002ovPDHLkV1mk}=w$!^ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_save.png b/app/src/main/res/drawable-hdpi/ic_stat_save.png deleted file mode 100644 index 34b7ab1d5c3e31a2cb25769986db7c4d99681be6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 513 zcmV+c0{;DpP)1?#{CDwibZ7uu^X#$FkudEsyMNI^i z6oTRl2wDgUn4O=+&BCxco4fAJ><3V?^YUxL)wGHU9LAL$z?k`y3s8bLIE}r3 zna+D~0?)-?_<91`!c~lQI5I|Y0YAzBdXEEHFsYo=;$7+q==E+esl0cUaF)I30_b)b zKpUt=z>MRm5=!P29&ROr-LR;W%yz6Z@a% z&@nuUe7FU*Eo=-8+`x6*!&kwXZnoexX~%I8x4KA>x1L}&4OGEdd{F#;->%QNj7obW zP6^|_Ay~LxaI6W=EMY3^@2KDq>XX`k*nL*QU*4-!rpD*J*00000NkvXXu0mjf DywK*e diff --git a/app/src/main/res/drawable-mdpi/ic_stat.png b/app/src/main/res/drawable-mdpi/ic_stat.png deleted file mode 100644 index 71651b3104b09c16912819dd9abb86c29abf3aeb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294 zcmV+>0oneEP)VR<^W;|AXWxqX=+<=@;@q=Ky3?rfVhul7CUB)^ds78E1NchSOviAeH}lv;2N zIUhi4yem+-?sXua3uGvIu`!?k0AQv)y@`VU)Bpeg07*qoM6N<$f=d)`tN;K2 diff --git a/app/src/main/res/drawable-mdpi/ic_stat_call.png b/app/src/main/res/drawable-mdpi/ic_stat_call.png deleted file mode 100644 index 962d811d8a2e4e89c007015cd72a767f25537bf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmV-c0jd6pP)j90%}9)nXuG??S}l33vq$AnBm9p%xm!AjYbMuoxr;@#i@_fx#{jgUv!(`mtQe zb<%rX?TKG3}6(GeZsGY4o@MqBosbz7cD#i#_^ImeIqK6Am^!yI+%$KOyD_%>_r6< zWIed(?btvWrzzwet=PyE9)kO5X6)U>4puSy7i26z;271^p8eF*{;u=`Z>SeRD!31j z4t7xw!o#^K`X|#k3qJ0ln-g9fNRTp`em>#frZ|v-CUJ|`U+NhQNRW}FwlzHE0G9&+ o0an30meIf=E^vj#p@Aav1s{IWhe)!_Hvj+t07*qoM6N<$f)GTFCIA2c diff --git a/app/src/main/res/drawable-mdpi/ic_stat_call_end.png b/app/src/main/res/drawable-mdpi/ic_stat_call_end.png deleted file mode 100644 index 4150353bbebc3f3dca431c94b3bc6aa28db361ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 351 zcmV-l0igbgP)^7{+l!UW@Xw&=8`K@)lpg%Fe>dhI|)U*+?wJl8p^T(acJDTPusnluv+|GU;dW z9QE{M20Lp0bynxPuKPasxvQ!wRQTVZ7VYTAD5fxtF$|ysb-xWwp*aLCVFi20;2Jl` zVjrtm4%!x^z6-C%3^qd0Gaiw{C5~{2E8OD=FG0J7Su~XjZx0>iP!y5DJSH%No^XaS zi8&kxZ4r5_A)O4b#(C%_&OQdqytog$3C}Ao&=MEk`kJ2<*eT(?iwjRIxP9ARm7c2Z+R|;oSfL002ovPDHLkV1i=9nAZRR diff --git a/app/src/main/res/drawable-mdpi/ic_stat_call_missed.png b/app/src/main/res/drawable-mdpi/ic_stat_call_missed.png deleted file mode 100644 index 958254dc75a2283ebe88cfff0c3a0e66e6e65072..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492 zcmV-&#C0oGtY4rEp(hr0}Q^cOKW zggMM&22WxQWOz%l52rC+#NaTR_<~EA2-8Z6Q^8(LV-mwf4QAuiFG6TZ>VFx#BD>32 zhf-04M>vQJc!fP35p0WZ*Ri^1;T(e@@O?9 z&3W9!ZaGhMDz1!iT*cdnZQ}7SrNw5+2)@Kg1>P8}!g0w^+zZoEmb4h_u@lRC6;H+2 iB-1v6a?$vI7(W4*8~V*(PTidV0000>7wES+6Ote6n0olNO-6--h0jII{NMQ zMy}ueaxKL&dsZH6FiSF+QpS_>-xyLyJLhSO#{RVOy|i7K=|I415E_4gUodE{4gO`@{pM z-XGk1ZV>z;Kp%*K0w}+10Zf6=2V%NU;sdz>aPWcB05~=Q7a$dTQh>C@P!a{mfr;3y z0#v|R?Dem%XafwzE)~E5cdJ-$T*UTf`pKW(gR5F5K661qtj|N8pT9{N8kxm8X1>F#1m+AqM(sTg!w7X znam+(_Rh?lLVWdF|1WFpOR4lPK&{B|1nWhGPvRW=MTD2plrmgFww5y;h9|%@u6*Yh zb0`lQp5Rh*1YZIGw&YH+q)`9>002ovPDHLkV1ilPjfwyO diff --git a/app/src/main/res/drawable-mdpi/ic_stat_save.png b/app/src/main/res/drawable-mdpi/ic_stat_save.png deleted file mode 100644 index b707a33cdbaef3e60e177ab5d7e771efbe39f0cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286 zcmV+(0pb3MP)r4z|(9M-))tq~?kq<2?cxCH{kc z1aO@IE+T-N1aKJvJSTvs2w;v!>{a@^xG$eI0&Ww#DbNQ7 z!33zGEU*p=j(;^#7T9!37iobE*atTFVJD!-%y1V-aTn+`0!F|H7y%<-1WF0uxE3^n z4$uh7$qUFO_c%BJAFi=q@Bp?!lBz&IIC34ogDdc)oc9ejL~lV&;7z_>gAv*MSRe+{ zuJK|WhSCK22oxuk(By_anxdTO_NWNt#ShmfXUU#Ittl!33jwmz9=Ur^ML}RbKsKq# zrnv~jG}&Di0y6*XkrnrhI2VDuCZFOWaG}YMaS=Gx>S&BzFEG4Qn*&LU(P_HICL_r`MAe;5bor^^t1%cZV4NV+eDjCu24^V0; zcR+=v8(Z}_e~m&<`~~J*yAOMy-F1GQe8#5s!&{;36)6H@Qj_w1@#N;tb!mt#m1FR! zO#B7Rif<*XZIxDVBUx6)5?}>9Dw8hAJMa={ps+h<`F(=o(f}=>2XxDAMk`{<6rK75 XCQG7JE2()W00000NkvXXu0mjf99QI3 diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_call.png b/app/src/main/res/drawable-xhdpi/ic_stat_call.png deleted file mode 100644 index 8a9181cb55f6f1470d35f18d6ab81f41c8702375..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 680 zcmV;Z0$2TsP)=FipO(X_`MMQ*!#2_JT z76UOz1(j&4==&M&_43ks=e~PeIj>2-&uK{ev z!qm=n(1p*+aXz(o9qcSA55uXw>*UL#EMuv?>tJ_tK6@fZwUT>&WgZWvO9V zYWEOA2v}bs0IsHX4Rd`s=u5(TsHDz#rB`7AWs6DF}IwPPVT5}AdO z)P602hfM-%xRcti5NyPcNJM)aXky@0WGVf`n$(U_uoU+rvoL|JsXe1$5k5p_Vgfr- zdq%;gTr{?vda$6xH9PY$J?Jhowh}lH2_V}eZj`v*%X}HuFoLJJiHqp|UlAu{XWX{B;?d99g^o O0000q diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_call_end.png b/app/src/main/res/drawable-xhdpi/ic_stat_call_end.png deleted file mode 100644 index e5a7cd06943c0b47b0a31faeb422b19058f3c4d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmV-W0RIR9p&?q%d|ag^ljBoc{4B9TZWstxL} z5Y5v<99vr+0)pE)u{iU#+Ts; z?%*lj;tR$xC7Y@E?AQ3)XSj<_EU%>TH8_LU_#91?i*bx#2<i>2c5KXK3H?`5 zd#St|AN5#=3mBcDOJle(rw;vD@3QdbN->Hn*o1~Gu_o*kPK&G!S*`$G839Bu_pt}_ zO9?gN5ME}8RU^POZ*aV52<#V*wY*d#0KCW1VnRc+5UFMW7%nE%H%pP9xK@S$7x8_T zwI37{Y88&myo{i;3;_-c%OWo?u(_1jS`6k8d4k<&EJJ{K*dfeJSvL~90%O87*`6uz??JW-)9m!fF%jSRuH20i zZsQL03e#e@utzFtKGv?qDqN4Xdxgt&=3BUkP(k0000>atGBYTMZtTvB4g_^kL?`MhBB+ZZBI&A&h$09Hm8fjA zC@D&!g3Pc&$<8r#quD?a(ZQxU&(p>FcK&Ss+4Jw2eYn{#EZB#Czu)_=wZ8RzYtNh4 zMjLIk(MGd?Yj7v-DlnGT$h{QH8l}A)A2z$)y=2*&XVmN(15XpH^181rl3nU4#xCsu0| zZ(~Kn#7E$)f&NTByopOuD!@^SXZObMhw&;_HB@|#feY|LCTaU;G7&R>Q9S!kY@NO6 zLr1d>bYVSq#!L?34P2hLokIL2nUx#HD*q534 zer#!)_&fvgSqbOkMW>I@cd#+@yES2~oUkv&R%)L3=?ui@#^56E57T%+DOVVsW2VJp?EzWMm97hVP^}Riw{C@858&nYg?_a5Ms|C zh?SVcN9b*}u9|?=Vd5axwOY@tfOXi=Y8{0Ur_o~cNL^-jEW?6UYy2N^>MV+4bRF)+ zV|YfY&by+(?T*(w@HptXzezan9??RFMZ@%`WN{2{!I2XIxx zR|m^+D_+AF(p_LWu|+X~U-7wAoo~mIdJA7H-Ge{IFA=mF{=|3E_3%iHqxd#VPlxd^ zb40ojt)8p!60XMkQj?aqJ;v}gp2m$hPs)phF}h=v-=B@%c=kyglX{~prleNn2Rvjp zcjTD$2l0EA85_mEIn7dvwNtuJp=IE81W zJ}SQnl+N%grLtcH%``yTTJK6HR%ag3Rtyvr-wFd|3}9Ox(XkpxT4?~j$|L%|Mv@Wi zse^$X(kWL92J(n*!pRy)PGNf;4BU_36fcT{xGj&U6F1{T0g~f**j$TEira&`@nwOy zC#64*yQU-S!u3^54C5*3{#&<3EaLV`{nd2a>F1c>?jmHj;HL_L6G5=3Ucz%?FN_I1 zUJ-i`_sl3hL$pB3iNPTF23M%z|IgV%YSTAK4P#mS9g0-q3ZfD=;|8p0jNGd6S4Qm3 j@(NcQZM4xw8}-0{A(K)GM@c8800000NkvXXu0mjf52Mm7 diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_delete.png b/app/src/main/res/drawable-xhdpi/ic_stat_delete.png deleted file mode 100644 index a1b828bf928a98888a4fbbf9204c1f87e7fef099..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 274 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUto1QL?AsLNtZ`pb=2THU)?7Y#z zvvFIYXjxM$m!6{Dan>E&;tCNrZ)tvecX)r1ob<#g&z_yTBXFKOzFuy}U7zbqbvbPH z!uM3ZzPtb7xmUJZ?%hq4@0Z|WV4hcK@a(|tro^qg`4<%amoDgCeyn^mUqaj5W9Hgy zIleR2f9*PL#ih`|z{G)txWV9XvV6m(wp$Hy^1@8}3L=CzbWi7GTz_LV+YiS%k8+zn zzTdIJs*bZT=g#skos$EP=_^*vNo-v0wf(?O-(PgSGY6|=t%}oS3j3^ HP6iYxK4Ox|hCr&Erq)fTj=7mtGdolMhfxuL@}D z1B|6t1@vkF;VJ`bl))mnyUN@yeGPS3_$j8zyJog z6QHU82`GVjqO&((0F3|#d?vaw20&8=kS=?`OYVS4&VW7em@{DXXM6?#2W)`>P_GJ@ z0d1jcc}E8T-mZRtbQb_K>1{W41~8Z2b#orTQhHNRzW^)Fy>_kr04$`pRO$%GDsu6HQ=ABZ_EYlLc)ok`y8mB#2-TY%Og?u(t67i24OA1usRs#7k`zun?Po zeFRbC1@D?*_GfW+*-6}FH#=uCS()bpocI6Cd(NCol9ZH`l>8T97(0v3(G@s_H`rHn zmUV*(e8BIX6TldL3G|i#Ch7oNO^|dP4vs z_`F7VSQPeyDt4i-=-f$?BnghoJC+1{X*ur$WTcAJRxTZB{a6Rp?H z(nI0@U lOV?nltOvZ3l9G~W`~_gtn965V%{c%7002ovPDHLkV1l$#2<-p> diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_save.png b/app/src/main/res/drawable-xhdpi/ic_stat_save.png deleted file mode 100644 index cdf622098ff5b9d5d88cf83cc291df8a493a9103..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 528 zcmV+r0`L8aP)DtIYan7If?tIoVkHU|3Vz%`5)niZ+z=4&z$@??Y=Yj0C{|)&8PuRyScnQ@ zVIf?9Qm)kzOCZSJ0;x zfga9pDZI7MX?%`NU=!!^!VmR2gWs_TBzRmj{7}CKf1eF5uz{l`1ZI`r50wh^aIl2H zjPiS-Qh`s{TSB0N*D(n6aHz>M(D*%&V5Nk>U6GtZ1Br_xgg-k*_*w+uJx&z}e;n_| z>{Z)c=nJl5CZqne^cU8L3i@OUWc}bM%Qvjxru0U74_}S9Y=-G(30$hE_#{}&5;%bM z(8&tW$KmZZSXX+k$I3dc=baL_#W@pwT-!1Hki-$`iP6PU;L*jR?UqeTVEzE(FsJ2N SEp&$f0000K9ub>Bf3{K>jY$tGF>Jab^EN0g8moUdiq4%+Y0ah3wmP}Bq!yCft~Ft zBP+58ZjMcmoL`pa=#*Q48;-sgU`|Ye4phFGQhiy%2vR#nkE3;c2Peg^X_3zEa^ zp{KjwtRU?k^mIRwTLjC320YzkpvkhJ-hd0ham#`_0t8*MENDl7pvQ7Tw<;*)9_u%# zvnr@9@G)ktRY9$Rf|{%f+7KwH#j2q7fr7SC5ci<}I>dMm@}!=Z`O5hvW7}2*Z4VIi z$nu?ZXMms~%g_qj}0#~?`3 zQ$=r|r}I!!gaiuu2A1ULoDE(&`fkgouVWG<;#`$3Wzq9@nd&|wGNwqA!bb}RDbD2u?9gkczlVaoFlb({><9L5Be P00000NkvXXu0mjfu8LpV diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_call.png b/app/src/main/res/drawable-xxhdpi/ic_stat_call.png deleted file mode 100644 index fbb9d4edc00d0f00d41672da468310ce0cea0249..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1227 zcmV;+1T_1JP){eHLm*K^1QAi-Ls8L7 zH;SZ}z;23Z4|bu87*1iBp<*Ixsf3j+TIFxC8HC8+x#-foCT^#O>(JttTls8Ta5X|DS!h3lnnd zN=7j?K1pCsoiA}lZe7U`>&MQ72JJz2Ze7VJ4Ei;pLA~u}P$zy&XwU(im0MRbFa=*F zH0UtS&aEpMVv*jE(4f9{GiWm2PiW8p=H=Fv3{1pJi49tjTURnL0Z%402sY%_l?;r- z{fQ0Qky}?Xa1w4xY|w$+x{`uLV(mypzc%|=yZ}EXGzdP(tt%Orjdh6)+MZiiGH@!M zNo>&Xn3P*v62w-2ue9sXUQEfYEeRNd>qI6o6+h?Jl@wfr^$Cm_5C_)9xiuvP)A3va zbM|9VZav8n(`+RUHEB#Aw&SwgT3QCK#O5Z+S7B#T`B0sD-D>mHh0XGgXN+gu?&5f zo;&7B5k(GbM1fQpcH@%VaaRiFiqrdn5(f2)@2K|95&au16s5w)I_=l9j9aiYcifdB z?(*+cu55Uq7)hIPb?(?JL)@dSEMd^#k+c;HbH`p8qVVeR222{jFA{uhW1c7*+=d^p z32QMYfwXiKCOs?e!OGGv4!0dmzH^qi)*kMU=oQ86Z{cRl#MI)c_my<2s<#APcvZQb zZ7?6>T#RerT{Fba*vO?qzsQ~cDXznR!w!*FuBNvH7Z?9nBmExzVqLlwT_xTz4KFlc zP8t5d3a#!f5xJwwn=px(F3;mCO#F{`tP&$2H5)Lar3MW$=~BF=@#%ILU*Hi#40+rj zQot!kPn|ugO!kR`ZL@d$z4!cPYPA|BVSzY>m${rgu?(u!jxOL6 zajnQa_KzAg3?fr`Bfb|W?>?>jI6VFg8Vr_-skc=eP+MtK^+$~qh)TBwSdF*Ef?lTT ztxQQAQa#{0*1SmV{x@JK_KU002ovPDHLkV1l;gL7M;o diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_call_end.png b/app/src/main/res/drawable-xxhdpi/ic_stat_call_end.png deleted file mode 100644 index e7182932d991af9b195f281bfdfde79a48eb0e64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 780 zcmV+n1M~ceP)CKnTJcb*S^AGoV`;rBb=ch0%@o@vuU2qAN3j`; z+UQ{=_TU80OUt^}WG{7G!h3QrJ!zjgDLsN)aaejB&&t|R>S->P;ZTb`4dHaQp75r$ zmdn_YrHRJ8hYweU_ z1lu(;bDmLjZIi`rVpRp>E(LE%hh~!*#rk%OePrV0R+A3Xmt-1SHdu;KDbL^{rBeQHh-%*6f)df(V~IOB@FFFl!_;3{^bFI$0%NC$nNNC$UM@H@6t zQK$#=@e*FlntsKK-WL?TFX*P;LkJ;+5JCtcgb+dqA%qY@7XJdjI^{v)=~DRs0000< KMNUMnLSTZ^G->Go diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_call_missed.png b/app/src/main/res/drawable-xxhdpi/ic_stat_call_missed.png deleted file mode 100644 index 6994f9339bb6f2bfab555ac9099d52730bb2aa01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1239 zcmV;|1StE7P)^0}?L;DMhdD!dB|G$3wzt>v-|5_6! z6ciK`6ciK`6ciK`BT&+BVe;0?8O7r@`cDz&oYB;8 zzL59Ns+?v8O8U;mr&S_pBc_z~n}YkRh%3?X3WDSScbKD3fu7&y!lB~2r2itEfvMddPc(3ikV5Pd64j$Z(X6C0 zL$5_i*gPIjmj3q=@m4F#-+BVf#JNdC{Mv#D?eZtyz?DJ;v+Wa-aYHz|S&T=7!dSYn z)d@y~=z12{VPdy+89NI<53eT<=7o}wJl`m!GM$YoA!4q;3&P21y9^5%{XU_%|3RvK zm^?eE@^G*jMun&v)XCB;wrcM)`U5Xx4Q6TK%?dB2AGhGe1(8$MI+w`r3r?pcx5We}<_&$R;c^8PV`hJa-tr(mpqyfh=815B;#`sy7 zE9=+Ng%gD>{(EyG3%w!`VOPFQofDY}xJ%rfa4!i&_~bU!Gxl9XWAvUt@IyUgzeP6I zivk_1XKX;+Pwci12y|0Ke@F0GJ!8|cQ=BrzFqU^fpbLeg@2ozTgu2yfjSTh+S9h~y z=tH=9yu~T=c@^Hy;O~f#EzEA#V4o04t#Vvg37fhY6&qYDY;Id+msZdIg$mtH%|+62 zye0?tc7$tx+cme*9l@L0z2hik%{$cpzK`L0U5c7&2!{l#@M8mkc4*=zN+V-)@RrJ3 z7o);usNCM!5pIxtQp5LmFejFwKA{j_ZfGygj$&XO!C82>%wP*6}%P*6}%P*Biq{sBd8lfobrZsh;~002ovPDHLkV1oCd BP@w<- diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_delete.png b/app/src/main/res/drawable-xxhdpi/ic_stat_delete.png deleted file mode 100644 index bd11b4c66ce16c9380af0941567031454e81d02e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 495 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2VBF^E;uumf=j|QCY>`Bfwu=JS zw2mnpT(IcKsriY@H#BZ!Cob-tI`x)|wC~ELy<3x>&%YQI;^J$-xLV}o#v7pmDS1uC zzf%uaKiGEqPI`OfwjXJEdP;pvJsUcNZO^RuYPa`L;hkgYIbRIQH{PgPAD1Bc{R40H zuZ_Lz7FVnG|8EktnRCao_Nd{{HSa5WHn08uhq?d5ABN9aLg^auAD=Z`-(r`tfS*~< zS~r^Wif$tpXNboFCnixg-V*uO#&+4xY*7aPZX2B5Y!I=akM!7HSI3Vtw^l<#WI{6Rr|o>)z@2`(^Ls2)>wf(<0$JXLvMA)Y0rWX0iKk z>)m^l)a{^r=fLr0oV#id%F4{HTHv`v)aGc~WuE`rdefu!?_zqsA?;7D?6ml;yfz10 zmlf6>_KZ2kz2`9hpE;j$9@@q|;+hs+{*(JzZ+u;e)N|>xk~)d|O8Yx*Opm|pYH<0C Tc#q~LA-$AAUfI2Rq+oH+;s6jaMsn)O}rI43A(#Fl}@6A3gXhG;HEf; zw}P~qJPwK0Az#jy7GkfD#2zqOk*g!b+j@ z-tbrDu>-AC-eBhNNcUw#0QD062oe7v>8avP% zTq<-%`QRZA=>X~#K#2k1?U-06gp2705oj{P@(`zH2y;x^M%f11)M=~6$_y4 z8w{WT3ZTE00`v~I3Z1tKct5D4`-RUEr>y{>X)Ayd1yG^@N)$ke0%$-#aVmhSTgR~g zs%{C*0P5d5&Q;>fIM4@NLnDB;YvUuH;)*&y%`_U&LtLG}xr_@qo`m@ipk?gU{Tb&( zO>LABfi`e|q&u19Y65-79URKN?~Yd!=pGK|-Ze`#fR?c*_nz4r0Q3V7a_^VD3ZQSj zGv{FL{j%2wXbX37B=>Gb)CXt@2XgOKO#cAInbWTxP@Fkc>HeQioHNj1PROY2Y5CQ-I002ovPDHLkV1jpi0Vn_f diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_reply.png b/app/src/main/res/drawable-xxhdpi/ic_stat_reply.png deleted file mode 100644 index 8d76eb3a9d61f3e9a46213febf13e86f51aa94d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1071 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 O00006c z{kRoZ;rybA6N{n@tb6>mzz|HqdAJVu;#s_pU(l(1okfv8#B*4I>x&qsVrboYsg!uq zrx#D+gLt)gqIaOHf`oUc3pGa>MScXw`=lfq`J2wwsH8H@h;?p74;$8SdEM05yIv&PyT#XBG zrr7h(EdG5FuEm{rK`bAiW3!lvdy2o`srecC9j*`$T|HY_48v?Z-^&4Yp8<5CQ(D$wz` z2^+;)+N{H+01NSL3FGO+&themRCbWF@q~DlFKbKL*9t)7W{WshnO#P3gTxo&8nI@V zsV^4bfZZZz7wYY?1_ookSRdO<4v@ZG03v6buoy@5G^itSnRx1}dW-Gr1t4;_3rqCm zv{jr~HoME|PJbxC0qtVj+x<)sZ?#n{IS1=c1t4~giy8^&vlawH|0@8jYb2n*TNF%x zEWlrl1XRXbVIwx`e+AgsNI*-q<~v|L=CvTl-Hms?XyjLIKW=U$pb=Q9`Xa2wX)VZc zcjG->oRC(j9gkv6qd~QaW8tcbumyK(rKf?75!Xe^EJ6p? zVF5-~l+zv)jg?FANy+1F7nc#*^rmqmZk3f)gstM}wp>BA;yuy7t+rEC z5z%1zSmPbDF41Cr3KPo?W`g)K+1gDJx|`(j1|{W);n}Ja5tX8)T)D-RLq2fk1Y1%Q(TD=l?G7*as6ho zcz-$gYGsF5^Lw_{Y$BL(;{MHsBJqFX716LiY?+cAZj3*RntYgaRJW3=(^)dDW#NBN-3q3Qc5YMlu}A5rIb=iDW#NBN-3q( aul)liT)NIM^wTc@00006IrrYVv%kqnnwfLv zti68ctiAVId!LSsWHOmdCX>lzGMP*!lgVTo}hy&jL?Fh;AoPvzk27*{^;sY(EB!a>y2y$;XXH(@pjfcYZqJlx=X z>E8#juFU)OgxMkh7AEKKn&N!P{$04Dto!wh76mwryKs9O$5l$|gs~WJZsPoUvTgP` ze`KU(0ruj(I2UKOc$`*}eT(rX>}=xvKg?R^kBqb|KpngBb}a6pZ40n<8t31I)xEN( z5?U0XQH0G{*aN%fi!k>4CeFVbmsf2^yD@Xkx<-tWohq zuO~DS;1I6BubMdEVQj3>rZw2t#CF%FC#_yUqq=pS8+Oih^D!32P7tH>cKb4sTNaw7@Z$*x0st}Kf z)Ii650#3%2I8gBSYxpD9m($__qZI+td22+U@ZTxt*6}E|=wNgthMJqOzrgw9xEEKK z*Wv-ARRPku>qHzrULe9AF=k)X#=RGb(N56}cLMk0nsQq_V6-DZI)4LxlN?ke!nMt= zo$_}UrE`m%5BFiL{1y)w?Fx{t*^nGGmAVKSTW7d_kw~oF+r;?~%?am^jC3YIx^7K+ zdW%HZjq4SJBN6krD4yXGVW+f_)xguK0O{IQ)4U1yV@yNGEYb@bL;|hI`FjlOXr~$7 z2#~J7cp4G*;~Hs*DkfP)Gu)@0ui_NPz)^w#^TcFrcM}mFPmW!s`3(0#TxOVNxUGWM zhuhGTO(&PXC$Cc;jU2>--CnmB)-=#b~ulV1f`okXY=IC?5Ik?q`wllpD@&>&*| zZYRzY8ktC8XDmCvWN=b)>`ujno(YlLx!y43^9K>pCu~WM9-rd;eWJ9PonIvlBJ67D z6ZYb5+4(&pi7+PS1CQdmJlg3oNrX3wr6u{v?*~bQ?EFk7Qw2CpB;`JYkK*IF5uYeH zZcM-b2yVa&`)&U~BMRnA@N6tg9qK3XWszJvE^<6Yd7hb=ylxzS#?AOFUXku~rZ!5P zLqqB`mtwi71AiKKh@@JrLua=u%#*kUAI8h^e4K8WJ9F`rzY1@`_eH*@7Y?6}I*y2? zlAjX8*$WKIn}JjC5|NwvrYNqolFjS~ld0`HL>L^!dHwcbM~K?&MPirak3`{QP#s@H zP2`ns5pB2#r}o>gGa~A;7mChqyNI>@3^CnO7t0y9;|pRHUrW`zo+8r3&%wvUx}Lu) z*YV?GY2oeoF@A_`;t6d$wx!?Qmd@Sp#D!j+P{+STE#g~Z@Njy+{r)tfW8JBFX|NrR z;%B%?><4~5UWOOrxi|-BHylgT(fG4-(z!26*RI67L_hQsu}7g3>Uc`*A^rj0pr1?G z#lEg>ctYnfz9yEEd{r!>Jr8H$nW8W0x~e7K&;?>y{Il=^T#he^Jpt|7UKbnC58>Nb zR)#;@ZPYtOsOg3SVhLg2#@|VtYelEqDM!T&yxJ0|m_#kZcSKC=Hr(tt0G|R7L(V;2 zwuM*@xmroPIHwx9M1+VtOw|zmT9+t5YAtL?}_1M6%4ZglN=VA*bB5%vlip$ zTgAAyD&~R!#JuBHyizM~f*9Z5shTgHG%{BNAbhz4=eJ_eHXV^^*zRFd>q3S86v&=l@@pD%!o?2}eY+-zsCE-Dv5z!eZ7gIKV1Zv{N~;I z%Gxc`)R%}cZP63)l*lEWYrtcDJBX0V0`82;uumf=j~nFEYU=U)`uoi z%_q6G1Z>#kp{x`Uk)@cSpXVT;lcX4t!dUjssen`IT9}i;RD~w{gr%(!8s9hWh}j@n zKk1I8uq}TL_m6X@4KANOGHx<) zm^Pq-VtLE2OCJ3D=t@!oSBc}vUXTDV`9x)o^d{jBhLzSSOY{Vgu?8)n`6IlVyk z{vl`G!{v88-v5raXj=Yo+x zWnOhtsEt9rq5Lud<2}cn*DNi+W4`90k=#uCbNOmjWgjKN|93uIy=qm~4gRywycD%B Ss~-nOK7*&LpUXO@geCwAq2jUt diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_message.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_message.png deleted file mode 100644 index 25a0765dae48746b9dfe7a4d83ecae37326c8199..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 592 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7Ro>U=sIqaSW-L^Y-rEF5y6l_K#n) zS?zB)Z3yzdslCBdv*X6is`M-emi=7o4;)&(AtYx_4hwhd)h8P-IHiQ87o9tE-}3XH zgkR?GH$U;2q>N;j~+slh~{Mm4S+W$HG_Sdhds?+^nSk-rw>Do(470*d-Uzu+`tDXPr TZtzoJN@4JH^>bP0l+XkK7ugNk diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_reply.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_reply.png deleted file mode 100644 index 2c5ea8764a174fcab899e8d5ba627b1a4397e11c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1231 zcmV;=1Tg!FP)xB8n>why)ab zATA6N44OnuG)_peQKKEf5vO#0T-?{4q`RuSUe&8QRbBV{57epO@4fTxJ?Gq86q!sW zlgVTwQFoqX! z0~SPURXdXSKZHu$KKrm1OQLnF1u5+e>XYA!|D4ibb`JJ)@cVT|Co|VA4 z_%2qvT6q(zqIGQxoQh9_1?vT4c-$br4N}_K8LLxI8OK{#9j)~=uu^@sok8ai)<$bS ziB!+8+D069{>D?$+7~#*%tKRiofok%O8n!oJy?K2;B739GGQUU3>F}ohSXS!DTCvD zb9?pEE?coQ%7hEl(_S2QUKh1jz#@DREWjY}YKQ@)2`lhHv;x5##)e1}R+^jTh$@WZ z_DB;J%IWB!$c~%T1O6~rglP7PoYIg^xO^O|K`0G89cDmj!bwIu9W`)Mv=QB8oq-Ce(nVOsMls*ofHb{61Z|CwV7{~1h~!Y zcVLWRS#+!|k)|zXsvQli0Yxzx|8_Hf8}5vbb4H|_a(4`)0Yy<1SSoGg4!8IZd!l2U z6=}!ZEFBHJ0Yx#ncX$lHw=m)2=on|Ee4VF`!ViT36JS05ZDPQK(Xq9KRJPbXtOgWC zQQ&6NOBq|D<7yjR=*Wk8=nN=|$raL}qYU`PFrD0&O2$KdrWbcRwuG@RI;KiU?aj-h zlzGMP*){{u1SU0wTWbj1Jw002ovPDHLkV1floNmKv; diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_save.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_save.png deleted file mode 100644 index f907c8e4209e332839dd6a7a659a08bdab7d6044..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1028 zcmV+f1pE7mP) z&r1|x7{|>-v@%HW(4}7**daRf4|wQO;H6U@>Kb$iy4F3U4hCK7P~agj65LA>6jX=k z2NaPQB1HZu6BJB~sMXz1hj%xI#a(x1-*=w(9iI=()qTF-&p0zX^Ex&)DT<;fisC;& zD=+|z0Plba;8Vu8ebT)*0X;wtSYhii4IGdvejCuw)+|2CBG4-#pkF$+)OCy}uTDT%HqvGtvnIU=cXzO29qobb&C9i|+}TFIk)M z7nlrqvvr8g14nHOn5g4}CxKm<^F@f;gP29vVilX0sF<(dn=uKrTKmwH0q$EA0Pw|{ z1Qn2&Rp5w?;Z#6!@-%v4Rsjvu*wv8=u)+dxIO%XIzz%CbPmjIQ` zr~qM9fG{dR7!@Fl3J^vG2%`doQ31lJ0AW;sFe*S86(EcX5Jm+EqXL9c0m7&NVKOJ+ zEpQ#U2D}7{vg2$@@B&@~mx1;gbGHE(fmfoFZcMNO{*d6^3_us=kLG+KNC9_%9dXN# z>xR{4=kH%dQSieLoXwq1TC*PvjoAOtJ} zyB!MH349aE=DmOdaNJe-k!;hL2UJC$o zldQvG@8xW5LixNGPz3tiRsTQRF<@OFUl0OTfISY&?*NvNSwZ2wfHFCU0)_>11tXw{ zc^Gf)st9PttRa$II~0rnFqfrwEeaSy=C~gvC;?#h)`!5}28!{Fcq+J>^^KVzAVTs%T0000 + + diff --git a/app/src/main/res/drawable/ic_notification_call.xml b/app/src/main/res/drawable/ic_notification_call.xml new file mode 100644 index 00000000..1c8636a9 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_call.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_call_end.xml b/app/src/main/res/drawable/ic_notification_call_end.xml new file mode 100644 index 00000000..0995ea01 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_call_end.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_call_missed.xml b/app/src/main/res/drawable/ic_notification_call_missed.xml new file mode 100644 index 00000000..14dba4a7 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_call_missed.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_delete.xml b/app/src/main/res/drawable/ic_notification_delete.xml new file mode 100644 index 00000000..55cad408 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_delete.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_message.xml b/app/src/main/res/drawable/ic_notification_message.xml new file mode 100644 index 00000000..5da59214 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_message.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_reply.xml b/app/src/main/res/drawable/ic_notification_reply.xml new file mode 100644 index 00000000..046a2bb0 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_reply.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_notification_save.xml b/app/src/main/res/drawable/ic_notification_save.xml new file mode 100644 index 00000000..3ddddc13 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_save.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 0bdb7dac..b8956455 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -271,6 +271,7 @@ Vastaa Talleta Puhelu soittajalta + soittaa Vastaamaton puhelu soittajalta Vastaamattomia puheluita %1$d vastaamatonta puhelua diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cf223274..809fb5d1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -256,6 +256,7 @@ Reply Save Incoming call from + is calling Missed call from Missed calls %1$d missed calls diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1ef9e1f9..1d90f0fa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,7 @@ runtimeLivedata = "1.9.4" composeMaterial3 = "1.4.0" navigationRuntimeAndroid = "2.9.6" composeMaterialIcons = "1.7.8" +media3CommonKtx = "1.8.0" [libraries] androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activityCompose" }