diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9987354e..d799627e 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -118,6 +118,17 @@
android:exported="false"
android:foregroundServiceType="dataSync" />
+
+
+
+
+
+
+
0) {
+ ((progress * 100) / total).toInt().coerceIn(0, 100)
+ } else {
+ -1
+ }
+ val bucket = if (percent < 0) -1 else percent / 25
+ val signature = "$currentTrackName|$currentStatus|$queueCount|$bucket"
+ if (signature == widgetSignature) return
+ widgetSignature = signature
+
+ val subtitle = when (currentStatus) {
+ "verification_required" -> "Verification required"
+ "rate_limited" -> "Rate limited, retrying..."
+ "waiting_wifi" -> "Waiting for Wi-Fi..."
+ "finalizing" -> "Finalizing..."
+ else -> buildString {
+ append(currentArtistName)
+ if (queueCount > 1) {
+ if (isNotEmpty()) append(" • ")
+ append("$queueCount in queue")
+ }
+ }
+ }
+ try {
+ DownloadQueueWidgetProvider.push(
+ this,
+ running = true,
+ title = currentTrackName.ifEmpty { "Downloading..." },
+ subtitle = subtitle,
+ percent = percent,
+ )
+ } catch (e: Exception) {
+ android.util.Log.w("DownloadService", "Widget update failed: ${e.message}")
+ }
}
private fun buildNotification(progress: Long, total: Long): Notification {
diff --git a/android/app/src/main/res/drawable/widget_download_bg.xml b/android/app/src/main/res/drawable/widget_download_bg.xml
new file mode 100644
index 00000000..ab808957
--- /dev/null
+++ b/android/app/src/main/res/drawable/widget_download_bg.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/android/app/src/main/res/layout/widget_download_queue.xml b/android/app/src/main/res/layout/widget_download_queue.xml
new file mode 100644
index 00000000..0b5e95de
--- /dev/null
+++ b/android/app/src/main/res/layout/widget_download_queue.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values-night-v31/colors.xml b/android/app/src/main/res/values-night-v31/colors.xml
new file mode 100644
index 00000000..4524607e
--- /dev/null
+++ b/android/app/src/main/res/values-night-v31/colors.xml
@@ -0,0 +1,7 @@
+
+
+ @android:color/system_neutral1_900
+ @android:color/system_neutral1_50
+ @android:color/system_neutral2_200
+ @android:color/system_accent1_200
+
diff --git a/android/app/src/main/res/values-night/colors.xml b/android/app/src/main/res/values-night/colors.xml
new file mode 100644
index 00000000..cd97213c
--- /dev/null
+++ b/android/app/src/main/res/values-night/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #1C1B1F
+ #E6E1E5
+ #CAC4D0
+
diff --git a/android/app/src/main/res/values-v31/colors.xml b/android/app/src/main/res/values-v31/colors.xml
new file mode 100644
index 00000000..769fafd2
--- /dev/null
+++ b/android/app/src/main/res/values-v31/colors.xml
@@ -0,0 +1,7 @@
+
+
+ @android:color/system_neutral1_10
+ @android:color/system_neutral1_900
+ @android:color/system_neutral2_700
+ @android:color/system_accent1_600
+
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
index beab31f7..74e1334d 100644
--- a/android/app/src/main/res/values/colors.xml
+++ b/android/app/src/main/res/values/colors.xml
@@ -1,4 +1,8 @@
#000000
+ #F3F3F3
+ #1C1B1F
+ #49454F
+ #1DB954
\ No newline at end of file
diff --git a/android/app/src/main/res/xml/widget_download_queue_info.xml b/android/app/src/main/res/xml/widget_download_queue_info.xml
new file mode 100644
index 00000000..b4310db8
--- /dev/null
+++ b/android/app/src/main/res/xml/widget_download_queue_info.xml
@@ -0,0 +1,8 @@
+
+