Reorganize Searchable data types

This commit is contained in:
MM20
2022-10-12 20:36:39 +02:00
parent a01b0aa03d
commit bcda89c211
98 changed files with 817 additions and 738 deletions
-1
View File
@@ -42,7 +42,6 @@ dependencies {
implementation(libs.koin.android)
implementation(project(":search"))
implementation(project(":preferences"))
implementation(project(":ktx"))
implementation(project(":base"))
@@ -5,16 +5,18 @@ import android.provider.ContactsContract
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.SearchableRepository
import de.mm20.launcher2.search.data.Contact
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
interface ContactRepository {
fun search(query: String): Flow<List<Contact>>
}
interface ContactRepository: SearchableRepository<Contact>
internal class ContactRepositoryImpl(
private val context: Context,
@@ -23,13 +25,13 @@ internal class ContactRepositoryImpl(
private val permissionsManager: PermissionsManager by inject()
private val dataStore: LauncherDataStore by inject()
override fun search(query: String): Flow<List<Contact>> {
override fun search(query: String): Flow<ImmutableList<Contact>> {
val searchContacts = dataStore.data.map { it.contactsSearch.enabled }
val hasPermission = permissionsManager.hasPermission(PermissionGroup.Contacts)
if (query.length < 3) {
return flow {
emit(emptyList())
emit(persistentListOf())
}
}
@@ -39,12 +41,12 @@ internal class ContactRepositoryImpl(
if (it) {
queryContacts(query)
} else {
emptyList()
persistentListOf()
}
}
}
private suspend fun queryContacts(query: String): List<Contact> {
private suspend fun queryContacts(query: String): ImmutableList<Contact> {
val results = withContext(Dispatchers.IO) {
val proj = arrayOf(
ContactsContract.RawContacts.CONTACT_ID,
@@ -67,6 +69,6 @@ internal class ContactRepositoryImpl(
}
results
}
return results
return results.toImmutableList()
}
}
@@ -6,14 +6,15 @@ import android.content.pm.PackageManager
import android.provider.ContactsContract
import androidx.core.content.ContextCompat
import de.mm20.launcher2.ktx.jsonObjectOf
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.Contact
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.search.Searchable
import org.json.JSONObject
class ContactSerializer : SearchableSerializer {
override fun serialize(searchable: Searchable): String {
override fun serialize(searchable: PinnableSearchable): String {
searchable as Contact
return jsonObjectOf(
"id" to searchable.id
@@ -25,7 +26,7 @@ class ContactSerializer : SearchableSerializer {
}
class ContactDeserializer(val context: Context) : SearchableDeserializer {
override fun deserialize(serialized: String): Searchable? {
override fun deserialize(serialized: String): PinnableSearchable? {
if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.READ_CONTACTS
@@ -3,20 +3,21 @@ package de.mm20.launcher2.search.data
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.provider.ContactsContract
import androidx.core.content.ContextCompat
import androidx.core.database.getStringOrNull
import androidx.core.graphics.drawable.toDrawable
import de.mm20.launcher2.contacts.R
import de.mm20.launcher2.icons.*
import de.mm20.launcher2.ktx.asBitmap
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.search.PinnableSearchable
import de.mm20.launcher2.search.Searchable
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.net.URLEncoder
class Contact(
data class Contact(
val id: Long,
val firstName: String,
val lastName: String,
@@ -27,12 +28,21 @@ class Contact(
val telegram: Set<ContactInfo>,
val whatsapp: Set<ContactInfo>,
val postals: Set<ContactInfo>,
) : Searchable() {
override val labelOverride: String? = null
) : Searchable, PinnableSearchable {
override val domain: String = Domain
override val key: String
get() = "contact://$id"
get() = "${Domain}://$id"
override val label: String
get() = "$firstName $lastName"
override fun overrideLabel(label: String): Contact {
return this.copy(labelOverride = label)
}
override val preferDetailsOverLaunch: Boolean = true
val summary: String
get() {
return phones.union(emails).joinToString(separator = ", ") { it.label }
@@ -69,7 +79,12 @@ class Contact(
)
}
override fun getLaunchIntent(context: Context): Intent {
override fun launch(context: Context, options: Bundle?): Boolean {
val intent = getLaunchIntent()
return context.tryStartActivity(intent, options)
}
private fun getLaunchIntent(): Intent {
val uri =
ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, id)
return Intent(Intent.ACTION_VIEW).setData(uri).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
@@ -202,7 +217,10 @@ class Contact(
)
}
const val Domain = "contact"
}
}
data class ContactInfo(