Implement custom legacy to adaptive icon transformations
This commit is contained in:
parent
5bd86e6f95
commit
bb211d4d6a
@ -117,6 +117,7 @@ dependencies {
|
||||
implementation(project(":contacts"))
|
||||
implementation(project(":crashreporter"))
|
||||
implementation(project(":currencies"))
|
||||
implementation(project(":customattrs"))
|
||||
implementation(project(":favorites"))
|
||||
implementation(project(":files"))
|
||||
implementation(project(":g-services"))
|
||||
|
||||
@ -12,6 +12,7 @@ import de.mm20.launcher2.badges.badgesModule
|
||||
import de.mm20.launcher2.calculator.calculatorModule
|
||||
import de.mm20.launcher2.calendar.calendarModule
|
||||
import de.mm20.launcher2.contacts.contactsModule
|
||||
import de.mm20.launcher2.customattrs.customAttrsModule
|
||||
import de.mm20.launcher2.debug.Debug
|
||||
import de.mm20.launcher2.favorites.favoritesModule
|
||||
import de.mm20.launcher2.files.filesModule
|
||||
@ -57,6 +58,7 @@ class LauncherApplication : Application(), CoroutineScope, ImageLoaderFactory {
|
||||
badgesModule,
|
||||
calendarModule,
|
||||
contactsModule,
|
||||
customAttrsModule,
|
||||
databaseModule,
|
||||
favoritesModule,
|
||||
filesModule,
|
||||
|
||||
@ -10,7 +10,8 @@ sealed interface CustomAttribute {
|
||||
fun toDatabaseEntity(key: String): CustomAttributeEntity
|
||||
|
||||
companion object {
|
||||
internal fun fromDatabaseEntity(entity: CustomAttributeEntity): CustomAttribute? {
|
||||
internal fun fromDatabaseEntity(entity: CustomAttributeEntity?): CustomAttribute? {
|
||||
if (entity == null) return null
|
||||
return when (entity.type) {
|
||||
CustomAttributeType.Label.value -> CustomLabel(
|
||||
label = entity.value
|
||||
|
||||
@ -1,8 +1,22 @@
|
||||
package de.mm20.launcher2.customattrs
|
||||
|
||||
import de.mm20.launcher2.database.AppDatabase
|
||||
import de.mm20.launcher2.search.data.Searchable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
interface CustomAttributesRepository {
|
||||
fun getCustomAttributes(searchable: Searchable, type: CustomAttributeType? = null): Flow<List<CustomAttribute>>
|
||||
fun getCustomIcon(searchable: Searchable): Flow<CustomIcon?>
|
||||
}
|
||||
|
||||
internal class CustomAttributesRepositoryImpl(
|
||||
private val appDatabase: AppDatabase,
|
||||
) : CustomAttributesRepository {
|
||||
override fun getCustomIcon(searchable: Searchable): Flow<CustomIcon?> {
|
||||
val dao = appDatabase.customAttrsDao()
|
||||
return dao.getCustomIcon(searchable.key)
|
||||
.map {
|
||||
CustomAttribute.fromDatabaseEntity(it) as? CustomIcon
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,5 +3,5 @@ package de.mm20.launcher2.customattrs
|
||||
import org.koin.dsl.module
|
||||
|
||||
val customAttrsModule = module {
|
||||
|
||||
single<CustomAttributesRepository> { CustomAttributesRepositoryImpl(get()) }
|
||||
}
|
||||
@ -28,6 +28,7 @@ abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun widgetDao(): WidgetDao
|
||||
abstract fun currencyDao(): CurrencyDao
|
||||
abstract fun backupDao(): BackupRestoreDao
|
||||
abstract fun customAttrsDao(): CustomAttrsDao
|
||||
|
||||
companion object {
|
||||
private var _instance: AppDatabase? = null
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package de.mm20.launcher2.database
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Query
|
||||
import de.mm20.launcher2.database.entities.CustomAttributeEntity
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface CustomAttrsDao {
|
||||
@Query("SELECT * FROM CustomAttributes WHERE type = 'icon' AND key = :key LIMIT 1")
|
||||
fun getCustomIcon(key: String) : Flow<CustomAttributeEntity?>
|
||||
}
|
||||
@ -53,5 +53,6 @@ dependencies {
|
||||
implementation(project(":search"))
|
||||
implementation(project(":applications"))
|
||||
implementation(project(":crashreporter"))
|
||||
implementation(project(":customattrs"))
|
||||
|
||||
}
|
||||
@ -5,6 +5,9 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.util.LruCache
|
||||
import de.mm20.launcher2.customattrs.AdaptifiedLegacyIcon
|
||||
import de.mm20.launcher2.customattrs.CustomAttributesRepository
|
||||
import de.mm20.launcher2.customattrs.CustomIcon
|
||||
import de.mm20.launcher2.icons.providers.*
|
||||
import de.mm20.launcher2.icons.transformations.LauncherIconTransformation
|
||||
import de.mm20.launcher2.icons.transformations.LegacyToAdaptiveTransformation
|
||||
@ -19,7 +22,8 @@ import kotlinx.coroutines.launch
|
||||
class IconRepository(
|
||||
val context: Context,
|
||||
private val iconPackManager: IconPackManager,
|
||||
private val dataStore: LauncherDataStore
|
||||
private val dataStore: LauncherDataStore,
|
||||
private val customAttributesRepository: CustomAttributesRepository,
|
||||
) {
|
||||
|
||||
private val appReceiver = object : BroadcastReceiver() {
|
||||
@ -93,36 +97,54 @@ class IconRepository(
|
||||
fun getIcon(searchable: Searchable, size: Int): Flow<LauncherIcon> = channelFlow {
|
||||
iconProviders.collectLatest { providers ->
|
||||
transformations.collectLatest { transformations ->
|
||||
var icon = cache.get(searchable.key)
|
||||
if (icon != null) {
|
||||
send(icon)
|
||||
return@collectLatest
|
||||
}
|
||||
customAttributesRepository.getCustomIcon(searchable).collectLatest { customIcon ->
|
||||
|
||||
val placeholder = placeholderProvider?.getIcon(searchable, size)
|
||||
placeholder?.let { send(it) }
|
||||
val transforms = getTransformations(customIcon) ?: transformations
|
||||
|
||||
for (provider in providers) {
|
||||
val ic = provider.getIcon(searchable, size)
|
||||
if (ic != null) {
|
||||
icon = ic
|
||||
break
|
||||
var icon = cache.get(searchable.key + customIcon.hashCode())
|
||||
if (icon != null) {
|
||||
send(icon)
|
||||
return@collectLatest
|
||||
}
|
||||
}
|
||||
if (icon != null) {
|
||||
if (icon is StaticLauncherIcon) {
|
||||
for (transformation in transformations) {
|
||||
icon = transformation.transform(icon as StaticLauncherIcon)
|
||||
|
||||
val placeholder = placeholderProvider?.getIcon(searchable, size)
|
||||
placeholder?.let { send(it) }
|
||||
|
||||
for (provider in providers) {
|
||||
val ic = provider.getIcon(searchable, size)
|
||||
if (ic != null) {
|
||||
icon = ic
|
||||
break
|
||||
}
|
||||
}
|
||||
if (icon != null) {
|
||||
if (icon is StaticLauncherIcon) {
|
||||
for (transformation in transforms) {
|
||||
icon = transformation.transform(icon as StaticLauncherIcon)
|
||||
}
|
||||
}
|
||||
|
||||
cache.put(searchable.key, icon)
|
||||
send(icon)
|
||||
cache.put(searchable.key + customIcon.hashCode(), icon)
|
||||
send(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTransformations(customIcon: CustomIcon?): List<LauncherIconTransformation>? {
|
||||
customIcon ?: return null
|
||||
if (customIcon is AdaptifiedLegacyIcon) {
|
||||
return listOf(
|
||||
LegacyToAdaptiveTransformation(
|
||||
foregroundScale = customIcon.fgScale,
|
||||
backgroundColor = customIcon.bgColor
|
||||
)
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
fun requestIconPackListUpdate() {
|
||||
scope.launch {
|
||||
|
||||
@ -5,5 +5,5 @@ import org.koin.dsl.module
|
||||
|
||||
val iconsModule = module {
|
||||
single { IconPackManager(androidContext()) }
|
||||
single { IconRepository(androidContext(), get(), get()) }
|
||||
single { IconRepository(androidContext(), get(), get(), get()) }
|
||||
}
|
||||
@ -7,13 +7,16 @@ import de.mm20.launcher2.icons.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
internal class LegacyToAdaptiveTransformation: LauncherIconTransformation {
|
||||
internal class LegacyToAdaptiveTransformation(
|
||||
private val foregroundScale: Float = 0.7f,
|
||||
private val backgroundColor: Int = 1,
|
||||
): LauncherIconTransformation {
|
||||
override suspend fun transform(icon: StaticLauncherIcon): StaticLauncherIcon {
|
||||
if (icon.backgroundLayer !is TransparentLayer) return icon
|
||||
|
||||
val bgColor = extractColor(icon.foregroundLayer)
|
||||
val bgColor = if (backgroundColor == 1) extractColor(icon.foregroundLayer) else backgroundColor
|
||||
return StaticLauncherIcon(
|
||||
foregroundLayer = scale(icon.foregroundLayer, 0.7f),
|
||||
foregroundLayer = scale(icon.foregroundLayer, foregroundScale),
|
||||
backgroundLayer = ColorLayer(bgColor)
|
||||
)
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ dependencyResolutionManagement {
|
||||
listOf("kotlin.stdlib", "kotlinx.coroutines.core", "kotlinx.coroutines.android")
|
||||
)
|
||||
|
||||
version("androidx.compose.compiler", "1.2.0")
|
||||
version("androidx.compose.compiler", "1.3.0-beta01")
|
||||
alias("androidx.compose.runtime")
|
||||
.to("androidx.compose.runtime", "runtime")
|
||||
.version("1.2.0-rc03")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user