fix(ci): scope integration Postgres discovery to this job's network #53

Merged
bvandeusen merged 262 commits from dev into main 2026-05-18 22:50:36 -04:00
Showing only changes of commit 6aec03fc02 - Show all commits
@@ -2,6 +2,7 @@ package com.fabledsword.minstrel.player
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.os.Bundle
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata import androidx.media3.common.MediaMetadata
import androidx.media3.common.Player import androidx.media3.common.Player
@@ -90,7 +91,12 @@ class PlayerController @Inject constructor(
val controller = val controller =
try { try {
connectController() connectController()
} catch (e: Exception) { } catch (
// Service-connection failure is a "show error, move on" boundary —
// any throwable from the Media3 IPC handshake gets surfaced via
// playbackError. Specific-exception handling buys nothing here.
@Suppress("TooGenericExceptionCaught") e: Throwable,
) {
uiStateInternal.value = uiStateInternal.value =
uiStateInternal.value.copy(playbackError = e.message ?: "Player unavailable") uiStateInternal.value.copy(playbackError = e.message ?: "Player unavailable")
return return
@@ -132,7 +138,13 @@ class PlayerController @Inject constructor(
{ {
try { try {
cont.resume(future.get()) cont.resume(future.get())
} catch (e: Exception) { } catch (
// ListenableFuture.get() throws ExecutionException +
// InterruptedException + CancellationException — handle
// them uniformly by forwarding to the continuation;
// the caller catches at the outer boundary.
@Suppress("TooGenericExceptionCaught") e: Throwable,
) {
cont.resumeWithException(e) cont.resumeWithException(e)
} }
}, },
@@ -141,19 +153,24 @@ class PlayerController @Inject constructor(
cont.invokeOnCancellation { future.cancel(/* mayInterruptIfRunning = */ false) } cont.invokeOnCancellation { future.cancel(/* mayInterruptIfRunning = */ false) }
} }
private fun TrackRef.toMediaItem(source: String?): MediaItem = private fun TrackRef.toMediaItem(source: String?): MediaItem {
MediaItem.Builder() val metadata = MediaMetadata.Builder()
.setTitle(title)
.setArtist(artistName)
.setAlbumTitle(albumTitle)
.apply {
if (source != null) setExtras(sourceExtras(source))
}
.build()
return MediaItem.Builder()
.setMediaId(id) .setMediaId(id)
.setUri(streamUrl) .setUri(streamUrl)
.setMediaMetadata( .setMediaMetadata(metadata)
MediaMetadata.Builder()
.setTitle(title)
.setArtist(artistName)
.setAlbumTitle(albumTitle)
.apply { source?.let { setExtras(android.os.Bundle().apply { putString(MINSTREL_SOURCE_KEY, it) }) } }
.build(),
)
.build() .build()
}
private fun sourceExtras(source: String): Bundle =
Bundle().apply { putString(MINSTREL_SOURCE_KEY, source) }
companion object { companion object {
const val MINSTREL_SOURCE_KEY: String = "minstrel_source" const val MINSTREL_SOURCE_KEY: String = "minstrel_source"