From 4aa02a89df534ac28229c51653c804b09f02ee4e Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Thu, 3 Jul 2025 22:46:14 +0200 Subject: [PATCH] Implement backup and restore for new theme types --- data/database/build.gradle.kts | 2 + .../database/entities/ColorsEntity.kt | 6 +- .../database/entities/ShapesEntity.kt | 5 +- .../database/entities/TransparenciesEntity.kt | 5 +- .../database/entities/TypographyEntity.kt | 5 +- .../mm20/launcher2/themes/ThemeRepository.kt | 101 +++++++++++++++--- 6 files changed, 108 insertions(+), 16 deletions(-) diff --git a/data/database/build.gradle.kts b/data/database/build.gradle.kts index 29d8ac0c..87ce3092 100644 --- a/data/database/build.gradle.kts +++ b/data/database/build.gradle.kts @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin.android) alias(libs.plugins.ksp) + alias(libs.plugins.kotlin.plugin.serialization) } android { @@ -54,5 +55,6 @@ dependencies { implementation(project(":core:i18n")) implementation(project(":core:ktx")) implementation(project(":core:preferences")) + implementation(project(":core:base")) } \ No newline at end of file diff --git a/data/database/src/main/java/de/mm20/launcher2/database/entities/ColorsEntity.kt b/data/database/src/main/java/de/mm20/launcher2/database/entities/ColorsEntity.kt index 2567c8a2..2c36347c 100644 --- a/data/database/src/main/java/de/mm20/launcher2/database/entities/ColorsEntity.kt +++ b/data/database/src/main/java/de/mm20/launcher2/database/entities/ColorsEntity.kt @@ -2,11 +2,15 @@ package de.mm20.launcher2.database.entities import androidx.room.Entity import androidx.room.PrimaryKey +import de.mm20.launcher2.serialization.UUIDSerializer +import kotlinx.serialization.Contextual +import kotlinx.serialization.Serializable import java.util.UUID +@Serializable @Entity(tableName = "Theme") data class ColorsEntity( - @PrimaryKey val id: UUID, + @Serializable(with = UUIDSerializer::class) @PrimaryKey val id: UUID, val name: String, val corePaletteA1: Int?, diff --git a/data/database/src/main/java/de/mm20/launcher2/database/entities/ShapesEntity.kt b/data/database/src/main/java/de/mm20/launcher2/database/entities/ShapesEntity.kt index 78b8736f..9debe031 100644 --- a/data/database/src/main/java/de/mm20/launcher2/database/entities/ShapesEntity.kt +++ b/data/database/src/main/java/de/mm20/launcher2/database/entities/ShapesEntity.kt @@ -2,11 +2,14 @@ package de.mm20.launcher2.database.entities import androidx.room.Entity import androidx.room.PrimaryKey +import de.mm20.launcher2.serialization.UUIDSerializer +import kotlinx.serialization.Serializable import java.util.UUID +@Serializable @Entity(tableName = "Shapes") data class ShapesEntity( - @PrimaryKey val id: UUID, + @Serializable(with = UUIDSerializer::class) @PrimaryKey val id: UUID, val name: String, val baseShape: String, diff --git a/data/database/src/main/java/de/mm20/launcher2/database/entities/TransparenciesEntity.kt b/data/database/src/main/java/de/mm20/launcher2/database/entities/TransparenciesEntity.kt index a04bfee7..d615007c 100644 --- a/data/database/src/main/java/de/mm20/launcher2/database/entities/TransparenciesEntity.kt +++ b/data/database/src/main/java/de/mm20/launcher2/database/entities/TransparenciesEntity.kt @@ -2,11 +2,14 @@ package de.mm20.launcher2.database.entities import androidx.room.Entity import androidx.room.PrimaryKey +import de.mm20.launcher2.serialization.UUIDSerializer +import kotlinx.serialization.Serializable import java.util.UUID +@Serializable @Entity(tableName = "Transparencies") data class TransparenciesEntity( - @PrimaryKey val id: UUID, + @Serializable(with = UUIDSerializer::class) @PrimaryKey val id: UUID, val name: String, val background: Float?, diff --git a/data/database/src/main/java/de/mm20/launcher2/database/entities/TypographyEntity.kt b/data/database/src/main/java/de/mm20/launcher2/database/entities/TypographyEntity.kt index 48a6ee83..7c52b96f 100644 --- a/data/database/src/main/java/de/mm20/launcher2/database/entities/TypographyEntity.kt +++ b/data/database/src/main/java/de/mm20/launcher2/database/entities/TypographyEntity.kt @@ -2,11 +2,14 @@ package de.mm20.launcher2.database.entities import androidx.room.Entity import androidx.room.PrimaryKey +import de.mm20.launcher2.serialization.UUIDSerializer +import kotlinx.serialization.Serializable import java.util.UUID +@Serializable @Entity(tableName = "Typography") data class TypographyEntity( - @PrimaryKey val id: UUID, + @Serializable(with = UUIDSerializer::class) @PrimaryKey val id: UUID, val name: String, val fonts: String? = null, diff --git a/data/themes/src/main/java/de/mm20/launcher2/themes/ThemeRepository.kt b/data/themes/src/main/java/de/mm20/launcher2/themes/ThemeRepository.kt index 5ac83cde..a94f1244 100644 --- a/data/themes/src/main/java/de/mm20/launcher2/themes/ThemeRepository.kt +++ b/data/themes/src/main/java/de/mm20/launcher2/themes/ThemeRepository.kt @@ -4,7 +4,11 @@ import android.content.Context import de.mm20.launcher2.backup.Backupable import de.mm20.launcher2.crashreporter.CrashReporter import de.mm20.launcher2.database.AppDatabase -import de.mm20.launcher2.themes.colors.Colors +import de.mm20.launcher2.database.entities.ColorsEntity +import de.mm20.launcher2.database.entities.ShapesEntity +import de.mm20.launcher2.database.entities.TransparenciesEntity +import de.mm20.launcher2.database.entities.TypographyEntity +import de.mm20.launcher2.serialization.Json import de.mm20.launcher2.themes.colors.ColorsRepository import de.mm20.launcher2.themes.shapes.ShapesRepository import de.mm20.launcher2.themes.transparencies.TransparenciesRepository @@ -27,12 +31,29 @@ class ThemeRepository( override suspend fun backup(toDir: File) = withContext(Dispatchers.IO) { val dao = database.themeDao() - val colors = dao.getAllColors().first().map { Colors(it) } - val data = LegacyThemeJson.encodeToString(colors) - val file = File(toDir, "themes.0000") - file.bufferedWriter().use { - it.write(data) + val colors = dao.getAllColors().first() + val colorsFile = File(toDir, "colors.0000") + colorsFile.bufferedWriter().use { + it.write(Json.Lenient.encodeToString(colors)) + } + + val shapes = dao.getAllShapes().first() + val shapesFile = File(toDir, "shapes.0000") + shapesFile.bufferedWriter().use { + it.write(Json.Lenient.encodeToString(shapes)) + } + + val transparencies = dao.getAllTransparencies().first() + val transparenciesFile = File(toDir, "transparencies.0000") + transparenciesFile.bufferedWriter().use { + it.write(Json.Lenient.encodeToString(transparencies)) + } + + val typographies = dao.getAllTypographies().first() + val typographiesFile = File(toDir, "typographies.0000") + typographiesFile.bufferedWriter().use { + it.write(Json.Lenient.encodeToString(typographies)) } } @@ -40,14 +61,14 @@ class ThemeRepository( val dao = database.themeDao() dao.deleteAllColors() - val files = - fromDir.listFiles { _, name -> name.startsWith("themes.") } + val colorFiles = + fromDir.listFiles { _, name -> name.startsWith("colors.") } ?: return@withContext - for (file in files) { + for (file in colorFiles) { val data = file.inputStream().reader().readText() - val colors: List = try { - LegacyThemeJson.decodeFromString(data) + val colors: List = try { + Json.Lenient.decodeFromString(data) } catch (e: SerializationException) { CrashReporter.logException(e) continue @@ -55,7 +76,63 @@ class ThemeRepository( CrashReporter.logException(e) continue } - dao.insertAllColors(colors.map { it.toEntity() }) + dao.insertAllColors(colors) } + + dao.deleteAllShapes() + val shapeFiles = + fromDir.listFiles { _, name -> name.startsWith("shapes.") } + ?: return@withContext + for (file in shapeFiles) { + val data = file.inputStream().reader().readText() + val shapes: List = try { + Json.Lenient.decodeFromString(data) + } catch (e: SerializationException) { + CrashReporter.logException(e) + continue + } catch (e: IllegalArgumentException) { + CrashReporter.logException(e) + continue + } + dao.insertAllShapes(shapes) + } + + dao.deleteAllTransparencies() + val transparencyFiles = + fromDir.listFiles { _, name -> name.startsWith("transparencies.") } + ?: return@withContext + for (file in transparencyFiles) { + val data = file.inputStream().reader().readText() + val transparencies: List = try { + Json.Lenient.decodeFromString(data) + } catch (e: SerializationException) { + CrashReporter.logException(e) + continue + } catch (e: IllegalArgumentException) { + CrashReporter.logException(e) + continue + } + dao.insertAllTransparencies(transparencies) + } + + dao.deleteAllTypographies() + val typographyFiles = + fromDir.listFiles { _, name -> name.startsWith("typographies.") } + ?: return@withContext + for (file in typographyFiles) { + val data = file.inputStream().reader().readText() + val typographies: List = try { + Json.Lenient.decodeFromString(data) + } catch (e: SerializationException) { + CrashReporter.logException(e) + continue + } catch (e: IllegalArgumentException) { + CrashReporter.logException(e) + continue + } + dao.insertAllTypographies(typographies) + } + + } } \ No newline at end of file