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
@@ -0,0 +1,43 @@
package de.mm20.launcher2.sdk.contacts
import android.net.Uri
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
data class Contact(
/**
* A unique and stable identifier for this contact.
*/
val id: String,
/**
* The display name for this contact.
* First name + last name, if applicable.
*/
val name: String,
/**
* List of phone numbers for this contact.
*/
val phoneNumbers: List<PhoneNumber> = emptyList(),
/**
* List of email addresses for this contact.
*/
val emailAddresses: List<EmailAddress> = emptyList(),
/**
* List of postal addresses for this contact.
*/
val postalAddresses: List<PostalAddress> = emptyList(),
/**
* List of additional actions to contact this person.
* For example, call on WhatsApp, send a message on Telegram, etc.
*/
val customActions: List<CustomContactAction> = emptyList(),
/**
* The URI of the contact's photo.
* This is a data URI, and the launcher will use it to display the contact's photo.
* If null, the launcher will use a default icon.
*/
val photoUri: Uri? = null,
)
@@ -0,0 +1,49 @@
package de.mm20.launcher2.sdk.contacts
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import de.mm20.launcher2.plugin.PluginType
import de.mm20.launcher2.plugin.config.QueryPluginConfig
import de.mm20.launcher2.plugin.contracts.ContactPluginContract.ContactColumns
import de.mm20.launcher2.plugin.contracts.SearchPluginContract
import de.mm20.launcher2.plugin.data.buildCursor
import de.mm20.launcher2.plugin.data.get
import de.mm20.launcher2.sdk.base.QueryPluginProvider
abstract class ContactProvider(
config: QueryPluginConfig,
) : QueryPluginProvider<String, Contact>(config) {
override fun getQuery(uri: Uri): String? {
return uri.getQueryParameter(SearchPluginContract.Params.Query)
}
override fun List<Contact>.toCursor(): Cursor {
return buildCursor(ContactColumns, this) {
put(ContactColumns.Id, it.id)
put(ContactColumns.Name, it.name)
put(ContactColumns.PhoneNumbers, it.phoneNumbers)
put(ContactColumns.EmailAddresses, it.emailAddresses)
put(ContactColumns.PostalAddresses, it.postalAddresses)
put(ContactColumns.CustomActions, it.customActions)
put(ContactColumns.PhotoUri, it.photoUri?.toString())
}
}
override fun Bundle.toResult(): Contact? {
return Contact(
id = get(ContactColumns.Id) ?: return null,
name = get(ContactColumns.Name) ?: return null,
phoneNumbers = get(ContactColumns.PhoneNumbers) ?: emptyList(),
emailAddresses = get(ContactColumns.EmailAddresses) ?: emptyList(),
postalAddresses = get(ContactColumns.PostalAddresses) ?: emptyList(),
customActions = get(ContactColumns.CustomActions) ?: emptyList(),
photoUri = get(ContactColumns.PhotoUri)?.let { Uri.parse(it) },
)
}
final override fun getPluginType(): PluginType {
return PluginType.ContactSearch
}
}