library: track whether an artist has credits

Add artists.credited, updated at the end of a sync that changed artists or
credits and backfilled on upgrade when relation data exists. Filter the
artist lists and the downloaded artist list on it, which keeps partially
synced libraries visible and hides display-only rows once credits are known.
This commit is contained in:
austinried
2026-10-18 05:59:36 +00:00
parent 4761772b9a
commit c64cdd5172
8 changed files with 2029 additions and 17 deletions
@@ -211,6 +211,32 @@ class MigrationsTest {
}
}
@Test
fun theArtistCreditedFlagsHideRowsWithoutCredits() =
runTest {
driver.open(":memory:").use { migrated ->
applySchema(migrated, 31)
migrated.execSQL(
"INSERT INTO sources (id, name, address, isActive, createdAt) VALUES (1, 's', 'http://x', 1, 0)",
)
migrated.execSQL("INSERT INTO artists (sourceId, id, name, albumCount) VALUES (1, 'a1', 'Alpha', 1)")
migrated.execSQL("INSERT INTO artists (sourceId, id, name, albumCount) VALUES (1, 'combo', 'Alpha & Beta', 1)")
migrated.execSQL(
"INSERT INTO albums (sourceId, id, artistId, name, albumArtist, created, songCount) " +
"VALUES (1, 'al1', 'a1', 'Album', 'Alpha', 0, 0)",
)
migrated.execSQL(
"INSERT INTO album_artists (sourceId, albumId, position, artistId, name) " +
"VALUES (1, 'al1', 0, 'a1', 'Alpha')",
)
MIGRATION_31_32.migrate(migrated)
assertEquals(1L, long(migrated, "SELECT credited FROM artists WHERE id = 'a1'"))
assertEquals(0L, long(migrated, "SELECT credited FROM artists WHERE id = 'combo'"))
}
}
private fun text(
connection: SQLiteConnection,
sql: String,
@@ -8,6 +8,7 @@ import androidx.sqlite.driver.bundled.BundledSQLiteDriver
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.subtracks.data.db.SubtracksDatabase
import com.subtracks.data.db.artistsDefaultQuery
import com.subtracks.data.model.Album
import com.subtracks.data.model.Artist
import com.subtracks.data.model.ArtistRef
@@ -19,6 +20,7 @@ import com.subtracks.data.model.PlaylistSong
import com.subtracks.data.model.Song
import com.subtracks.data.model.SongDownload
import com.subtracks.data.model.Source
import com.subtracks.data.prefs.ArtistSort
import com.subtracks.data.source.MusicSource
import com.subtracks.data.source.StarType
import kotlinx.coroutines.flow.Flow
@@ -27,7 +29,6 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.test.runTest
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -1071,13 +1072,20 @@ class SyncServiceTest {
insertSource()
val source =
FakeMusicSource(
artists = listOf(artist("a1", "Alpha"), artist("combo", "Alpha & Beta")),
artists =
listOf(
artist("a1", "Alpha").copy(playCount = 5, played = 100),
artist("combo", "Alpha & Beta").copy(playCount = 5, played = 100),
),
albums = listOf(album("al1")),
songs = listOf(song("s1")),
songs = listOf(song("s1").copy(playCount = 5, played = 100)),
)
SyncService(db, source).sync()
assertEquals(false, db.libraryDao().artistOnce(1, "combo")!!.credited)
assertEquals(true, db.libraryDao().artistOnce(1, "a1")!!.credited)
assertEquals(
listOf("a1"),
db
@@ -1086,6 +1094,23 @@ class SyncServiceTest {
.allRows()
.map { it.id },
)
val query = artistsDefaultQuery(1, 0, "alpha", ArtistSort.Name, false)
assertEquals(
listOf("a1"),
db
.libraryDao()
.artistsByName(1, 0, "alpha")
.allRows()
.map { it.id },
)
assertEquals(
listOf("a1"),
db
.libraryDao()
.artistsPaging(query)
.allRows()
.map { it.id },
)
assertEquals(
listOf("a1"),
db
@@ -1094,6 +1119,52 @@ class SyncServiceTest {
.first()
.map { it.id },
)
assertEquals(
listOf("a1"),
db
.libraryDao()
.homeMostPlayedArtists(1)
.allRows()
.map { it.id },
)
}
@Test
fun downloadedArtistsHidesNamesThatAreOnlyDisplayStrings() =
runTest {
insertSource()
val source =
FakeMusicSource(
artists = listOf(artist("a1", "Alpha"), artist("combo", "Alpha & Beta")),
albums =
listOf(
album("al1").copy(
artistId = "combo",
albumArtist = "Alpha & Beta",
artists = listOf(ArtistRef("a1", "Alpha")),
),
),
songs =
listOf(
song("s1").copy(
artistId = "combo",
artist = "Alpha & Beta",
artists = listOf(ArtistRef("a1", "Alpha")),
),
),
)
SyncService(db, source).sync()
db.downloadDao().upsert(SongDownload(1, "s1", DownloadStatus.Completed))
assertEquals(
listOf("a1"),
db
.libraryDao()
.downloadedArtists(1)
.allRows()
.map { it.id },
)
}
@Test