Multiple widget panels (#1805)

* Initial approach

* Add a new setting so users can choose the amount of widgets screens

* Extract indexed string

* Remove unnecessary Migration6

* Make HomeComponent use the Default widget id

* Add defaultParentId to initial widgets for fresh launch

* Fix migration path
This commit is contained in:
Fidel Montesino
2026-02-16 18:46:01 +00:00
committed by GitHub
parent 682ddfb22e
commit adfff23e67
18 changed files with 296 additions and 58 deletions

View File

@@ -39,14 +39,17 @@ import de.mm20.launcher2.database.migrations.Migration_22_23
import de.mm20.launcher2.database.migrations.Migration_23_24
import de.mm20.launcher2.database.migrations.Migration_24_25
import de.mm20.launcher2.database.migrations.Migration_25_26
import de.mm20.launcher2.database.migrations.Migration_26_27
import de.mm20.launcher2.database.migrations.Migration_27_28
import de.mm20.launcher2.database.migrations.Migration_28_29
import de.mm20.launcher2.database.migrations.Migration_29_30
import de.mm20.launcher2.database.migrations.Migration_30_31
import de.mm20.launcher2.database.migrations.Migration_6_7
import de.mm20.launcher2.database.migrations.Migration_7_8
import de.mm20.launcher2.database.migrations.Migration_8_9
import de.mm20.launcher2.database.migrations.Migration_9_10
import de.mm20.launcher2.ktx.toBytes
import de.mm20.launcher2.preferences.WidgetScreenTarget
import java.util.UUID
@Database(
@@ -64,7 +67,7 @@ import java.util.UUID
ShapesEntity::class,
TransparenciesEntity::class,
TypographyEntity::class,
], version = 30, exportSchema = true
], version = 31, exportSchema = true
)
@TypeConverters(ComponentNameConverter::class)
abstract class AppDatabase : RoomDatabase() {
@@ -129,15 +132,19 @@ abstract class AppDatabase : RoomDatabase() {
)
)
val defaultParentId = WidgetScreenTarget.Default.scopeId
db.execSQL(
"INSERT INTO Widget (`type`, `position`, `id`) VALUES " +
"('weather', 0, ?)," +
"('music', 1, ?)," +
"('calendar', 2, ?);",
"INSERT INTO Widget (`type`, `position`, `id`, `parentId`) VALUES " +
"('weather', 0, ?, ?)," +
"('music', 1, ?, ?)," +
"('calendar', 2, ?, ?);",
arrayOf(
UUID.randomUUID().toBytes(),
defaultParentId.toBytes(),
UUID.randomUUID().toBytes(),
UUID.randomUUID().toBytes()
defaultParentId.toBytes(),
UUID.randomUUID().toBytes(),
defaultParentId.toBytes()
)
)
}
@@ -163,13 +170,14 @@ abstract class AppDatabase : RoomDatabase() {
Migration_23_24(),
Migration_24_25(),
Migration_25_26(),
Migration_26_27(),
Migration_27_28(),
Migration_28_29(),
Migration_29_30(),
Migration_30_31(),
).build()
if (_instance == null) _instance = instance
return instance
}
}
}

View File

@@ -0,0 +1,11 @@
package de.mm20.launcher2.database.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration_26_27: Migration(26, 27) {
override fun migrate(db: SupportSQLiteDatabase) {
// Nothing to do
}
}

View File

@@ -0,0 +1,20 @@
package de.mm20.launcher2.database.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import de.mm20.launcher2.ktx.toBytes
import de.mm20.launcher2.preferences.WidgetScreenTarget
class Migration_30_31 : Migration(30, 31) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL(
"""
UPDATE Widget
SET parentId = ?
WHERE parentId IS NULL
""".trimIndent(),
arrayOf(WidgetScreenTarget.Default.scopeId.toBytes()),
)
}
}