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 4cb8bdfb..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_call.png b/app/src/main/res/drawable-hdpi/ic_stat_call.png deleted file mode 100644 index fe82d6d2..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_call.png and /dev/null differ 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 5bcc20b6..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_call_end.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_call_missed.png b/app/src/main/res/drawable-hdpi/ic_stat_call_missed.png deleted file mode 100644 index 2796f0f2..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_call_missed.png and /dev/null differ 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 08df7d8e..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_delete.png and /dev/null differ 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 f6822daa..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_message.png and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_stat_reply.png b/app/src/main/res/drawable-hdpi/ic_stat_reply.png deleted file mode 100644 index 5b534554..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_reply.png and /dev/null differ 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 34b7ab1d..00000000 Binary files a/app/src/main/res/drawable-hdpi/ic_stat_save.png and /dev/null differ 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 71651b31..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat.png and /dev/null differ 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 962d811d..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_call.png and /dev/null differ 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 4150353b..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_call_end.png and /dev/null differ 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 958254dc..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_call_missed.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_delete.png b/app/src/main/res/drawable-mdpi/ic_stat_delete.png deleted file mode 100644 index 8f10392c..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_message.png b/app/src/main/res/drawable-mdpi/ic_stat_message.png deleted file mode 100644 index ed25696b..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_message.png and /dev/null differ diff --git a/app/src/main/res/drawable-mdpi/ic_stat_reply.png b/app/src/main/res/drawable-mdpi/ic_stat_reply.png deleted file mode 100644 index 5df1ed8d..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_reply.png and /dev/null differ 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 b707a33c..00000000 Binary files a/app/src/main/res/drawable-mdpi/ic_stat_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat.png b/app/src/main/res/drawable-xhdpi/ic_stat.png deleted file mode 100644 index ba8d4dc1..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat.png and /dev/null differ 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 8a9181cb..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_call.png and /dev/null differ 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 e5a7cd06..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_call_end.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_call_missed.png b/app/src/main/res/drawable-xhdpi/ic_stat_call_missed.png deleted file mode 100644 index eebfd2bb..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_call_missed.png and /dev/null differ 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 a1b828bf..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_message.png b/app/src/main/res/drawable-xhdpi/ic_stat_message.png deleted file mode 100644 index 2563516f..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_message.png and /dev/null differ diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_reply.png b/app/src/main/res/drawable-xhdpi/ic_stat_reply.png deleted file mode 100644 index 8e06d70a..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_reply.png and /dev/null differ 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 cdf62209..00000000 Binary files a/app/src/main/res/drawable-xhdpi/ic_stat_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat.png b/app/src/main/res/drawable-xxhdpi/ic_stat.png deleted file mode 100644 index 62bb3f73..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat.png and /dev/null differ 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 fbb9d4ed..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_call.png and /dev/null differ 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 e7182932..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_call_end.png and /dev/null differ 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 6994f933..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_call_missed.png and /dev/null differ 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 bd11b4c6..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_delete.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_message.png b/app/src/main/res/drawable-xxhdpi/ic_stat_message.png deleted file mode 100644 index d1cbcd36..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_message.png and /dev/null differ 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 8d76eb3a..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_reply.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_save.png b/app/src/main/res/drawable-xxhdpi/ic_stat_save.png deleted file mode 100644 index 27419440..00000000 Binary files a/app/src/main/res/drawable-xxhdpi/ic_stat_save.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_call.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_call.png deleted file mode 100644 index c7d63781..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_call.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_call_end.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_call_end.png deleted file mode 100644 index f3fc8614..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_call_end.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_call_missed.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_call_missed.png deleted file mode 100644 index cfc5e179..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_call_missed.png and /dev/null differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_stat_delete.png b/app/src/main/res/drawable-xxxhdpi/ic_stat_delete.png deleted file mode 100644 index a8358eb7..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_delete.png and /dev/null differ 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 25a0765d..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_message.png and /dev/null differ 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 2c5ea876..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_reply.png and /dev/null differ 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 f907c8e4..00000000 Binary files a/app/src/main/res/drawable-xxxhdpi/ic_stat_save.png and /dev/null differ diff --git a/app/src/main/res/drawable/ic_notification_b.xml b/app/src/main/res/drawable/ic_notification_b.xml new file mode 100644 index 00000000..8d343d88 --- /dev/null +++ b/app/src/main/res/drawable/ic_notification_b.xml @@ -0,0 +1,9 @@ + + + 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" }