fix: polish pass — dark mode, notifications, icons, edge-to-edge

- Wrap SettingsScreen in Scaffold to fix invisible text in dark mode
- Fix notification showing raw ICY metadata instead of parsed track info
- Add proper white-on-transparent notification icon
- Create branded adaptive launcher icon (amber tower on BlueGray900)
- Add edge-to-edge support with proper window inset handling
- Add About section to Settings with version and app info
- Enable BuildConfig generation for version display

Made-with: Cursor
This commit is contained in:
cottongin
2026-03-10 21:18:48 -04:00
parent 5a59b3a86b
commit d381e80828
17 changed files with 468 additions and 30 deletions

View File

@@ -36,6 +36,7 @@ android {
} }
buildFeatures { buildFeatures {
compose = true compose = true
buildConfig = true
} }
} }

View File

@@ -11,6 +11,8 @@
<application <application
android:name=".RadioApplication" android:name=".RadioApplication"
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.Radio247"> android:theme="@style/Theme.Radio247">

View File

@@ -7,6 +7,7 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.enableEdgeToEdge
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
@@ -26,6 +27,7 @@ import xyz.cottongin.radio247.ui.theme.Radio247Theme
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
val requestNotificationPermission = rememberLauncherForActivityResult( val requestNotificationPermission = rememberLauncherForActivityResult(

View File

@@ -0,0 +1,14 @@
package xyz.cottongin.radio247.audio
object MetadataFormatter {
fun formatTrackInfo(metadata: IcyMetadata?, fallback: String = "\u266A"): String {
if (metadata == null) return fallback
return when {
metadata.artist != null && metadata.title != null ->
"${metadata.artist} \u2014 ${metadata.title}"
metadata.title != null -> metadata.title
metadata.artist != null -> metadata.artist
else -> fallback
}
}
}

View File

@@ -9,6 +9,7 @@ import androidx.core.app.NotificationCompat
import android.support.v4.media.session.MediaSessionCompat import android.support.v4.media.session.MediaSessionCompat
import xyz.cottongin.radio247.R import xyz.cottongin.radio247.R
import xyz.cottongin.radio247.audio.IcyMetadata import xyz.cottongin.radio247.audio.IcyMetadata
import xyz.cottongin.radio247.audio.MetadataFormatter
import xyz.cottongin.radio247.data.model.Station import xyz.cottongin.radio247.data.model.Station
class NotificationHelper(private val context: Context) { class NotificationHelper(private val context: Context) {
@@ -41,11 +42,11 @@ class NotificationHelper(private val context: Context) {
.setContentText( .setContentText(
when { when {
isReconnecting -> "Reconnecting..." isReconnecting -> "Reconnecting..."
metadata?.title != null -> metadata.raw metadata != null -> MetadataFormatter.formatTrackInfo(metadata, fallback = "Playing")
else -> "Playing" else -> "Playing"
} }
) )
.setSmallIcon(R.drawable.ic_radio_placeholder) .setSmallIcon(R.drawable.ic_notification)
.setOngoing(true) .setOngoing(true)
.setStyle( .setStyle(
androidx.media.app.NotificationCompat.MediaStyle() androidx.media.app.NotificationCompat.MediaStyle()

View File

@@ -26,12 +26,16 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBars
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.layout.wrapContentWidth
@@ -81,6 +85,7 @@ import androidx.compose.ui.draw.clipToBounds
import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.luminance import androidx.compose.ui.graphics.luminance
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
@@ -109,6 +114,7 @@ import coil3.size.Size
import xyz.cottongin.radio247.R import xyz.cottongin.radio247.R
import xyz.cottongin.radio247.RadioApplication import xyz.cottongin.radio247.RadioApplication
import xyz.cottongin.radio247.audio.IcyMetadata import xyz.cottongin.radio247.audio.IcyMetadata
import xyz.cottongin.radio247.audio.MetadataFormatter
import xyz.cottongin.radio247.audio.StreamInfo import xyz.cottongin.radio247.audio.StreamInfo
import xyz.cottongin.radio247.service.PlaybackState import xyz.cottongin.radio247.service.PlaybackState
import com.skydoves.cloudy.cloudy import com.skydoves.cloudy.cloudy
@@ -432,7 +438,8 @@ private fun ArtworkImage(
Image( Image(
painter = painterResource(R.drawable.ic_radio_placeholder), painter = painterResource(R.drawable.ic_radio_placeholder),
contentDescription = null, contentDescription = null,
modifier = Modifier.size(120.dp) modifier = Modifier.size(120.dp),
colorFilter = ColorFilter.tint(contrastingTextColor(bgColor))
) )
} }
} }
@@ -903,13 +910,16 @@ private fun PortraitContent(
val cardShape = RoundedCornerShape(14.dp) val cardShape = RoundedCornerShape(14.dp)
val backBtnShape = RoundedCornerShape(10.dp) val backBtnShape = RoundedCornerShape(10.dp)
val statusBarPadding = WindowInsets.statusBars.asPaddingValues().calculateTopPadding()
val navBarPadding = WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
Box(modifier = Modifier.fillMaxSize()) { Box(modifier = Modifier.fillMaxSize()) {
Column(modifier = Modifier.fillMaxSize()) { Column(modifier = Modifier.fillMaxSize()) {
Box( Box(
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.fillMaxWidth() .fillMaxWidth()
.padding(start = 24.dp, end = 24.dp, top = 48.dp, bottom = 8.dp), .padding(start = 24.dp, end = 24.dp, top = statusBarPadding + 48.dp, bottom = 8.dp),
contentAlignment = Alignment.Center contentAlignment = Alignment.Center
) { ) {
ArtworkImage( ArtworkImage(
@@ -968,12 +978,12 @@ private fun PortraitContent(
} }
} }
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(navBarPadding + 8.dp))
} }
Box( Box(
modifier = Modifier modifier = Modifier
.padding(start = 12.dp, top = 12.dp) .padding(start = 12.dp, top = statusBarPadding + 12.dp)
.size(40.dp) .size(40.dp)
.clip(backBtnShape) .clip(backBtnShape)
.background(bgColor.copy(alpha = 0.5f)) .background(bgColor.copy(alpha = 0.5f))
@@ -1135,16 +1145,8 @@ private fun OverlayCards(
} }
} }
private fun formatTrackInfo(metadata: IcyMetadata?): String { private fun formatTrackInfo(metadata: IcyMetadata?): String =
if (metadata == null) return "\u266A" MetadataFormatter.formatTrackInfo(metadata)
return when {
metadata.artist != null && metadata.title != null ->
"${metadata.artist} \u2014 ${metadata.title}"
metadata.title != null -> metadata.title
metadata.artist != null -> metadata.artist
else -> "\u266A"
}
}
private fun formatElapsed(millis: Long): String { private fun formatElapsed(millis: Long): String {
if (millis <= 0) return "0s" if (millis <= 0) return "0s"

View File

@@ -32,6 +32,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
import androidx.compose.material3.SliderDefaults import androidx.compose.material3.SliderDefaults
import androidx.compose.material3.Switch import androidx.compose.material3.Switch
@@ -106,7 +107,9 @@ fun SettingsScreen(
} }
} }
Column(modifier = modifier.fillMaxSize()) { Scaffold(
modifier = modifier.fillMaxSize(),
topBar = {
TopAppBar( TopAppBar(
title = { Text("Settings") }, title = { Text("Settings") },
navigationIcon = { navigationIcon = {
@@ -120,10 +123,12 @@ fun SettingsScreen(
navigationIconContentColor = MaterialTheme.colorScheme.onSurface navigationIconContentColor = MaterialTheme.colorScheme.onSurface
) )
) )
}
) { innerPadding ->
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(innerPadding)
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.padding(16.dp) .padding(16.dp)
) { ) {
@@ -256,6 +261,35 @@ fun SettingsScreen(
HorizontalDivider() HorizontalDivider()
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
// ── ABOUT ──
SectionHeader("ABOUT")
Text(
text = "24/7 Radio",
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurface
)
Text(
text = "Version ${xyz.cottongin.radio247.BuildConfig.VERSION_NAME}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Personal-use internet radio streaming app with ultra-low latency playback and Icecast/Shoutcast metadata support.",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = xyz.cottongin.radio247.BuildConfig.APPLICATION_ID,
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.6f)
)
Spacer(modifier = Modifier.height(24.dp))
HorizontalDivider()
Spacer(modifier = Modifier.height(24.dp))
// ── RESET ── // ── RESET ──
SectionHeader("RESET") SectionHeader("RESET")
SettingRow("Also delete saved stations/playlists") { SettingRow("Also delete saved stations/playlists") {

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h108v108h-108z" />
</vector>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<!-- Adaptive icon safe zone: 72dp centered in 108dp (18dp inset each side) -->
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M52,28h4v40h-4z" />
<!-- Tower base / tripod -->
<path
android:fillColor="#FFC107"
android:pathData="M42,72l12,-8l12,8z" />
<path
android:fillColor="#FFC107"
android:pathData="M44,72h20v3h-20z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M54,28m-3,0a3,3 0,1 1,6 0a3,3 0,1 1,-6 0" />
<!-- Inner broadcast waves (left) -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="2.5"
android:strokeLineCap="round"
android:pathData="M42,42a12,12 0,0 1,0 -14" />
<!-- Inner broadcast waves (right) -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="2.5"
android:strokeLineCap="round"
android:pathData="M66,42a12,12 0,0 0,0 -14" />
<!-- Outer broadcast waves (left) -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="2.5"
android:strokeLineCap="round"
android:pathData="M34,48a22,22 0,0 1,0 -26" />
<!-- Outer broadcast waves (right) -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="2.5"
android:strokeLineCap="round"
android:pathData="M74,48a22,22 0,0 0,0 -26" />
</vector>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Radio tower with broadcast waves -->
<!-- Tower body -->
<path
android:fillColor="#FFFFFF"
android:pathData="M11,2h2v16h-2z" />
<!-- Tower base -->
<path
android:fillColor="#FFFFFF"
android:pathData="M8,20l4,-4l4,4z" />
<!-- Left wave inner -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M7.5,7.5a5,5 0,0 1,0 -5" />
<!-- Right wave inner -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M16.5,7.5a5,5 0,0 0,0 -5" />
<!-- Left wave outer -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M4.5,9.5a9,9 0,0 1,0 -9" />
<!-- Right wave outer -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M19.5,9.5a9,9 0,0 0,0 -9" />
</vector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<!-- Background -->
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h48v48h-48z" />
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M22.5,10h3v22h-3z" />
<!-- Tower base -->
<path
android:fillColor="#FFC107"
android:pathData="M16,34l8,-5l8,5z" />
<path
android:fillColor="#FFC107"
android:pathData="M17,34h14v2h-14z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M24,10m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
<!-- Inner waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M17,20a7,7 0,0 1,0 -8" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M31,20a7,7 0,0 0,0 -8" />
<!-- Outer waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M12,24a13,13 0,0 1,0 -16" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M36,24a13,13 0,0 0,0 -16" />
</vector>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<!-- Background -->
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h48v48h-48z" />
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M22.5,10h3v22h-3z" />
<!-- Tower base -->
<path
android:fillColor="#FFC107"
android:pathData="M16,34l8,-5l8,5z" />
<path
android:fillColor="#FFC107"
android:pathData="M17,34h14v2h-14z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M24,10m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
<!-- Inner waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M17,20a7,7 0,0 1,0 -8" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M31,20a7,7 0,0 0,0 -8" />
<!-- Outer waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M12,24a13,13 0,0 1,0 -16" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M36,24a13,13 0,0 0,0 -16" />
</vector>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<!-- Background -->
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h48v48h-48z" />
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M22.5,10h3v22h-3z" />
<!-- Tower base -->
<path
android:fillColor="#FFC107"
android:pathData="M16,34l8,-5l8,5z" />
<path
android:fillColor="#FFC107"
android:pathData="M17,34h14v2h-14z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M24,10m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
<!-- Inner waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M17,20a7,7 0,0 1,0 -8" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M31,20a7,7 0,0 0,0 -8" />
<!-- Outer waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M12,24a13,13 0,0 1,0 -16" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M36,24a13,13 0,0 0,0 -16" />
</vector>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<!-- Background -->
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h48v48h-48z" />
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M22.5,10h3v22h-3z" />
<!-- Tower base -->
<path
android:fillColor="#FFC107"
android:pathData="M16,34l8,-5l8,5z" />
<path
android:fillColor="#FFC107"
android:pathData="M17,34h14v2h-14z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M24,10m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
<!-- Inner waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M17,20a7,7 0,0 1,0 -8" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M31,20a7,7 0,0 0,0 -8" />
<!-- Outer waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M12,24a13,13 0,0 1,0 -16" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M36,24a13,13 0,0 0,0 -16" />
</vector>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="48"
android:viewportHeight="48">
<!-- Background -->
<path
android:fillColor="#0D1B2A"
android:pathData="M0,0h48v48h-48z" />
<!-- Tower mast -->
<path
android:fillColor="#FFC107"
android:pathData="M22.5,10h3v22h-3z" />
<!-- Tower base -->
<path
android:fillColor="#FFC107"
android:pathData="M16,34l8,-5l8,5z" />
<path
android:fillColor="#FFC107"
android:pathData="M17,34h14v2h-14z" />
<!-- Antenna tip -->
<path
android:fillColor="#FFD54F"
android:pathData="M24,10m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0" />
<!-- Inner waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M17,20a7,7 0,0 1,0 -8" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFC107"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M31,20a7,7 0,0 0,0 -8" />
<!-- Outer waves -->
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M12,24a13,13 0,0 1,0 -16" />
<path
android:fillColor="#00000000"
android:strokeColor="#FFB300"
android:strokeWidth="1.5"
android:strokeLineCap="round"
android:pathData="M36,24a13,13 0,0 0,0 -16" />
</vector>