Improve tag emoji assignment

This commit is contained in:
MM20
2024-11-11 20:48:04 +01:00
parent 76ee00f404
commit a21dde5741
20 changed files with 569 additions and 69 deletions
+1
View File
@@ -49,6 +49,7 @@ dependencies {
ksp(libs.androidx.roomcompiler)
api(libs.androidx.room)
implementation(libs.koin.android)
implementation(libs.emoji4j)
implementation(project(":core:i18n"))
implementation(project(":core:ktx"))
@@ -36,6 +36,7 @@ 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_6_7
import de.mm20.launcher2.database.migrations.Migration_7_8
import de.mm20.launcher2.database.migrations.Migration_8_9
@@ -55,7 +56,7 @@ import java.util.UUID
SearchActionEntity::class,
ThemeEntity::class,
PluginEntity::class,
], version = 26, exportSchema = true
], version = 27, exportSchema = true
)
@TypeConverters(ComponentNameConverter::class)
abstract class AppDatabase : RoomDatabase() {
@@ -154,6 +155,7 @@ abstract class AppDatabase : RoomDatabase() {
Migration_23_24(),
Migration_24_25(),
Migration_25_26(),
Migration_26_27(),
).build()
if (_instance == null) _instance = instance
return instance
@@ -0,0 +1,72 @@
package de.mm20.launcher2.database.migrations
import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase
import android.util.Log
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.sigpwned.emoji4j.core.Grapheme
import com.sigpwned.emoji4j.core.GraphemeMatcher
import de.mm20.launcher2.ktx.jsonObjectOf
class Migration_26_27 : Migration(26, 27) {
override fun migrate(db: SupportSQLiteDatabase) {
Log.d("Tags-Migration", "Migrating tags")
db.query("SELECT DISTINCT value FROM CustomAttributes WHERE type = 'tag'").use { cursor ->
while (cursor.moveToNext()) {
val oldName = cursor.getString(0)
val (emoji, newName) = oldName.splitLeadingEmoji()
if (emoji != null) {
db.update(
"CustomAttributes",
SQLiteDatabase.CONFLICT_FAIL,
ContentValues().apply {
put("value", newName)
}, "type = 'tag' AND value = ?",
arrayOf(oldName)
)
db.insert(
"CustomAttributes",
SQLiteDatabase.CONFLICT_REPLACE,
ContentValues().apply {
put("key", "tag://$newName")
put("type", "icon")
put("value", jsonObjectOf(
"type" to "custom_text_icon",
"text" to emoji,
"color" to 0,
).toString())
}
)
db.update(
"Searchable",
SQLiteDatabase.CONFLICT_IGNORE,
ContentValues().apply {
put("key", "tag://$newName")
put("searchable", jsonObjectOf(
"tag" to newName
).toString())
},
"key = ?",
arrayOf("tag://$oldName")
)
}
}
}
}
fun String.splitLeadingEmoji(): Pair<String?, String> {
val matcher = GraphemeMatcher(this)
if (!matcher.find()) return null to this.trim()
val grapheme = matcher.grapheme()
if (grapheme?.type == Grapheme.Type.EMOJI && matcher.start() == 0) {
val end = matcher.end()
val emoji = this.substring(0, end)
val tagName = this.substring(end).takeIf { it.isNotBlank() }
if (tagName == null) return emoji to emoji
return emoji to tagName
}
return null to this.trim()
}
}