feat(android): port cached_home_index (M8 4.2 slice 9)
Mirrors flutter_client/lib/cache/db.dart's CachedHomeIndex — per-item
rows that drive the Home screen sections (Recently Added Albums,
Rediscover Albums/Artists, Most Played Tracks, Last Played Artists).
Composite PK (section, position) — exactly one row per slot per
section; sync replaces in-place via upsert. entityType ("album" /
"artist" / "track") dispatches per-tile hydration to the right
per-entity endpoint when the Home screen renders.
DAO surface fits the sync flow:
- observeBySection (Flow) for the Home composables
- getBySection (suspend) for one-shot sync reads
- upsertAll for sync writes
- deleteBySection for replace-all on a section sync
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import androidx.room.TypeConverters
|
||||
import com.fabledsword.minstrel.cache.db.dao.AudioCacheIndexDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedAlbumDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedArtistDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedHomeIndexDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedLikeDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedMutationDao
|
||||
import com.fabledsword.minstrel.cache.db.dao.CachedPlaylistDao
|
||||
@@ -17,6 +18,7 @@ import com.fabledsword.minstrel.cache.db.dao.SyncMetadataDao
|
||||
import com.fabledsword.minstrel.cache.db.entities.AudioCacheIndexEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedAlbumEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedArtistEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedHomeIndexEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedLikeEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedMutationEntity
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedPlaylistEntity
|
||||
@@ -52,6 +54,7 @@ import com.fabledsword.minstrel.cache.db.entities.SyncMetadataEntity
|
||||
AudioCacheIndexEntity::class,
|
||||
CachedMutationEntity::class,
|
||||
CachedResumeStateEntity::class,
|
||||
CachedHomeIndexEntity::class,
|
||||
],
|
||||
version = 1,
|
||||
exportSchema = true,
|
||||
@@ -69,4 +72,5 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun audioCacheIndexDao(): AudioCacheIndexDao
|
||||
abstract fun cachedMutationDao(): CachedMutationDao
|
||||
abstract fun cachedResumeStateDao(): CachedResumeStateDao
|
||||
abstract fun cachedHomeIndexDao(): CachedHomeIndexDao
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.fabledsword.minstrel.cache.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.fabledsword.minstrel.cache.db.entities.CachedHomeIndexEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CachedHomeIndexDao {
|
||||
@Query(
|
||||
"SELECT * FROM cached_home_index " +
|
||||
"WHERE section = :section ORDER BY position ASC",
|
||||
)
|
||||
fun observeBySection(section: String): Flow<List<CachedHomeIndexEntity>>
|
||||
|
||||
@Query(
|
||||
"SELECT * FROM cached_home_index " +
|
||||
"WHERE section = :section ORDER BY position ASC",
|
||||
)
|
||||
suspend fun getBySection(section: String): List<CachedHomeIndexEntity>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
suspend fun upsertAll(rows: List<CachedHomeIndexEntity>)
|
||||
|
||||
/** Replace-all pattern; sync wipes a section then re-inserts. */
|
||||
@Query("DELETE FROM cached_home_index WHERE section = :section")
|
||||
suspend fun deleteBySection(section: String)
|
||||
|
||||
@Query("DELETE FROM cached_home_index")
|
||||
suspend fun clear()
|
||||
}
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
package com.fabledsword.minstrel.cache.db.entities
|
||||
|
||||
import androidx.room.Entity
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
/**
|
||||
* Per-item row driving the Home screen sections. Mirrors
|
||||
* `flutter_client/lib/cache/db.dart`'s `CachedHomeIndex` Drift table.
|
||||
*
|
||||
* `section` is one of (matching /api/home keys):
|
||||
* - "recently_added_albums"
|
||||
* - "rediscover_albums"
|
||||
* - "rediscover_artists"
|
||||
* - "most_played_tracks"
|
||||
* - "last_played_artists"
|
||||
*
|
||||
* `entityType` is "album" | "artist" | "track" — dispatches hydration
|
||||
* to the right per-entity endpoint when a tile is rendered.
|
||||
*
|
||||
* The composite PK (section, position) means there's exactly one row
|
||||
* per slot per section; sync replaces in-place by upsert.
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "cached_home_index",
|
||||
primaryKeys = ["section", "position"],
|
||||
)
|
||||
data class CachedHomeIndexEntity(
|
||||
val section: String,
|
||||
val position: Int,
|
||||
val entityType: String,
|
||||
val entityId: String,
|
||||
val fetchedAt: Instant = Clock.System.now(),
|
||||
)
|
||||
Reference in New Issue
Block a user