Restructure contacts search for plugins

This commit is contained in:
MM20
2025-04-05 17:18:22 +02:00
parent 04dd12ee96
commit cab93f87aa
22 changed files with 417 additions and 278 deletions
@@ -1,14 +1,13 @@
package de.mm20.launcher2.search
import android.content.Context
import android.net.Uri
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Person
import de.mm20.launcher2.icons.ColorLayer
import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.icons.TextLayer
import de.mm20.launcher2.icons.VectorLayer
import de.mm20.launcher2.search.contact.CustomContactChannel
import de.mm20.launcher2.search.contact.CustomContactAction
import de.mm20.launcher2.search.contact.EmailAddress
import de.mm20.launcher2.search.contact.PhoneNumber
import de.mm20.launcher2.search.contact.PostalAddress
@@ -18,7 +17,7 @@ interface Contact : SavableSearchable {
val phoneNumbers: List<PhoneNumber>
val emailAddresses: List<EmailAddress>
val postalAddresses: List<PostalAddress>
val contactChannels: List<CustomContactChannel>
val customActions: List<CustomContactAction>
val summary: String
get() {
@@ -3,6 +3,7 @@ package de.mm20.launcher2.preferences
import android.content.Context
import de.mm20.launcher2.preferences.migrations.Migration2
import de.mm20.launcher2.preferences.migrations.Migration3
import de.mm20.launcher2.preferences.migrations.Migration4
import de.mm20.launcher2.settings.BaseSettings
internal class LauncherDataStore(
@@ -14,6 +15,7 @@ internal class LauncherDataStore(
migrations = listOf(
Migration2(),
Migration3(),
Migration4(),
),
) {
@@ -52,7 +52,9 @@ data class LauncherSettingsData internal constructor(
val fileSearchProviders: Set<String> = setOf("local"),
@Deprecated("Use contactSearchProviders `local` instead")
val contactSearchEnabled: Boolean = true,
val contactSearchProviders: Set<String> = setOf("local"),
val contactSearchCallOnTap: Boolean = false,
@Deprecated("Use calendarSearchProviders `local` instead")
@@ -0,0 +1,23 @@
package de.mm20.launcher2.preferences.migrations
import androidx.datastore.core.DataMigration
import de.mm20.launcher2.preferences.LauncherSettingsData
class Migration4 : DataMigration<LauncherSettingsData> {
override suspend fun cleanUp() {
}
override suspend fun migrate(currentData: LauncherSettingsData): LauncherSettingsData {
return currentData.copy(
schemaVersion = 4,
contactSearchProviders = setOfNotNull(
if (currentData.contactSearchEnabled) "local" else null,
)
)
}
override suspend fun shouldMigrate(currentData: LauncherSettingsData): Boolean {
return currentData.schemaVersion < 4
}
}
@@ -6,11 +6,20 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
class ContactSearchSettings internal constructor(private val dataStore: LauncherDataStore) {
val enabled: Flow<Boolean>
get() = dataStore.data.map { it.contactSearchEnabled }.distinctUntilChanged()
fun setEnabled(enabled: Boolean) {
dataStore.update { it.copy(contactSearchEnabled = enabled) }
val enabledProviders: Flow<Set<String>>
get() = dataStore.data.map { it.contactSearchProviders }.distinctUntilChanged()
fun isProviderEnabled(provider: String) = dataStore.data.map { it.contactSearchProviders.contains(provider) }
fun setProviderEnabled(provider: String, enabled: Boolean) {
dataStore.update {
if (enabled) {
it.copy(contactSearchProviders = it.contactSearchProviders + provider)
} else {
it.copy(contactSearchProviders = it.contactSearchProviders - provider)
}
}
}
val callOnTap: Flow<Boolean>
@@ -5,4 +5,5 @@ enum class PluginType {
Weather,
LocationSearch,
Calendar,
ContactSearch,
}
@@ -1,6 +1,6 @@
package de.mm20.launcher2.plugin.contracts
import de.mm20.launcher2.search.contact.CustomContactChannel
import de.mm20.launcher2.search.contact.CustomContactAction
import de.mm20.launcher2.search.contact.EmailAddress
import de.mm20.launcher2.search.contact.PhoneNumber
import de.mm20.launcher2.search.contact.PostalAddress
@@ -21,7 +21,7 @@ abstract class ContactPluginContract {
val PhoneNumbers = column<List<PhoneNumber>>("phone_numbers")
val EmailAddresses = column<List<EmailAddress>>("email_addresses")
val PostalAddresses = column<List<PostalAddress>>("postal_addresses")
val ContactChannels = column<List<CustomContactChannel>>("contact_channels")
val CustomActions = column<List<CustomContactAction>>("custom_actions")
val PhotoUri = column<String>("photo_uri")
}
@@ -26,7 +26,7 @@ data class PostalAddress(
* Custom contact channel, for example, WhatsApp message, Telegram video call, etc.
*/
@Serializable
data class CustomContactChannel(
data class CustomContactAction(
val label: String,
/**
* The data URI that is passed to the Intent.