Skip to content

Commit b38fcb0

Browse files
committed
This commit introduces major database optimizations and UI performance improvements, primarily focusing on search efficiency through FTS4 and reducing recomposition overhead in the player.
### Database & Search - **FTS4 Search Integration:** Added `songs_fts` virtual table and Room triggers to provide indexed full-text search for song titles and artist names. Replaced `LIKE` queries with `MATCH` for significantly faster search performance. - **Source Type Indexing:** Introduced a `source_type` column (Local, Telegram, GDrive, etc.) to the `songs` table to replace expensive URI scheme string checks in repository and DAO queries. - **Schema Migrations:** Added migrations (34→35, 35→36) to handle the new `source_type` column and initialize the FTS4 search table. ### Performance & Optimization - **Player State Consolidation:** Refactored `PlayerViewModel` to consolidate multiple infrequent preference flows into a single `player_config_slice`. This prevents excessive recompositions in the `UnifiedPlayerSheet` when individual settings change. - **Lazy List Improvements:** Added `contentType` and explicit `key` parameters to several lazy lists (Library, Search, Recently Played) to improve scroll performance and item recycling. - **Deferred Rendering:** Optimized screen transitions for Album, Artist, and Genre detail screens by reducing delays and tuning heavy list population. - **SmartImage Sizing:** Implemented `targetSize` hints for `SmartImage` in list contexts to optimize memory usage and image loading. - **Cached Filtering:** Implemented a cached directory filter in `MusicRepositoryImpl` that recomputes only when directory preferences change. ### Features & Bug Fixes - **Lyrics Import Security:** Refactored lyrics file validation into a more robust, asynchronous utility with improved error handling and security checks. - **Theme Generation:** Enhanced `ThemeStateHolder` with a request-based generation mechanism and "eager" loading options to improve color scheme availability for album art. - **MediaStore Search:** Optimized `MediaStoreSongRepository` to fetch multiple user preferences concurrently during search operations.
1 parent 3b4bcfd commit b38fcb0

31 files changed

Lines changed: 5441 additions & 333 deletions

app/schemas/com.theveloper.pixelplay.data.database.PixelPlayDatabase/35.json

Lines changed: 2397 additions & 0 deletions
Large diffs are not rendered by default.

app/schemas/com.theveloper.pixelplay.data.database.PixelPlayDatabase/36.json

Lines changed: 2433 additions & 0 deletions
Large diffs are not rendered by default.

app/src/androidTest/java/com/theveloper/pixelplay/data/database/MusicDaoTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class MusicDaoTest {
2626
fun createDb() {
2727
val context = ApplicationProvider.getApplicationContext<Context>()
2828
db = Room.inMemoryDatabaseBuilder(context, PixelPlayDatabase::class.java)
29+
.addCallback(PixelPlayDatabase.createRuntimeArtifactsCallback())
2930
.allowMainThreadQueries() // Permite consultas en el hilo principal para tests
3031
.build()
3132
musicDao = db.musicDao()

app/src/androidTest/java/com/theveloper/pixelplay/data/database/PixelPlayDatabaseMigrationTest.kt

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,23 @@ class PixelPlayDatabaseMigrationTest {
1717
@get:Rule
1818
val helper = MigrationTestHelper(
1919
InstrumentationRegistry.getInstrumentation(),
20-
PixelPlayDatabase::class.java.canonicalName,
20+
requireNotNull(PixelPlayDatabase::class.java.canonicalName),
2121
FrameworkSQLiteOpenHelperFactory()
2222
)
2323

2424
@After
2525
fun tearDown() {
2626
val context = InstrumentationRegistry.getInstrumentation().targetContext
27-
for (version in 25..33) {
27+
for (version in 25..35) {
2828
context.deleteDatabase(databaseNameFor(version))
2929
}
3030
context.deleteDatabase(DB_NAME_33_TO_34)
31+
context.deleteDatabase(DB_NAME_35_TO_36)
3132
}
3233

3334
@Test
3435
fun migrateEveryExportedSchemaToLatest() {
35-
for (startVersion in 25..33) {
36+
for (startVersion in 25..35) {
3637
helper.createDatabase(databaseNameFor(startVersion), startVersion).close()
3738

3839
helper.runMigrationsAndValidate(
@@ -50,7 +51,7 @@ class PixelPlayDatabaseMigrationTest {
5051

5152
helper.runMigrationsAndValidate(
5253
DB_NAME_33_TO_34,
53-
PixelPlayDatabaseVersion.LATEST,
54+
34,
5455
true,
5556
PixelPlayDatabase.MIGRATION_33_34
5657
).let { db ->
@@ -78,14 +79,36 @@ class PixelPlayDatabaseMigrationTest {
7879
}
7980
}
8081

82+
@Test
83+
fun migration35To36AddsSongsFtsTable() {
84+
helper.createDatabase(DB_NAME_35_TO_36, 35).close()
85+
86+
helper.runMigrationsAndValidate(
87+
DB_NAME_35_TO_36,
88+
36,
89+
true,
90+
PixelPlayDatabase.MIGRATION_35_36
91+
).let { db ->
92+
val cursor = db.query("SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'songs_fts'")
93+
try {
94+
assertTrue(cursor.moveToFirst())
95+
assertEquals("songs_fts", cursor.getString(0))
96+
} finally {
97+
cursor.close()
98+
db.close()
99+
}
100+
}
101+
}
102+
81103
private fun databaseNameFor(startVersion: Int): String = "migration-test-$startVersion"
82104

83105
private object PixelPlayDatabaseVersion {
84-
const val LATEST = 34
106+
const val LATEST = 36
85107
}
86108

87109
companion object {
88110
private const val DB_NAME_33_TO_34 = "migration-test-33-to-34"
111+
private const val DB_NAME_35_TO_36 = "migration-test-35-to-36"
89112

90113
private val ALL_MIGRATIONS = arrayOf(
91114
PixelPlayDatabase.MIGRATION_25_26,
@@ -96,7 +119,9 @@ class PixelPlayDatabaseMigrationTest {
96119
PixelPlayDatabase.MIGRATION_30_31,
97120
PixelPlayDatabase.MIGRATION_31_32,
98121
PixelPlayDatabase.MIGRATION_32_33,
99-
PixelPlayDatabase.MIGRATION_33_34
122+
PixelPlayDatabase.MIGRATION_33_34,
123+
PixelPlayDatabase.MIGRATION_34_35,
124+
PixelPlayDatabase.MIGRATION_35_36
100125
)
101126
}
102127
}

app/src/androidTest/java/com/theveloper/pixelplay/data/worker/SyncWorkerTest.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class SyncWorkerTest {
7070
fun setUp() {
7171
context = ApplicationProvider.getApplicationContext()
7272
database = Room.inMemoryDatabaseBuilder(context, PixelPlayDatabase::class.java)
73+
.addCallback(PixelPlayDatabase.createRuntimeArtifactsCallback())
7374
.allowMainThreadQueries() // Para tests, está bien.
7475
.build()
7576
musicDao = database.musicDao()

0 commit comments

Comments
 (0)