refactor(contacts): one Context.hasContactsPermission() helper
The READ_CONTACTS check was written out three times (data source, RootScreen resume trigger, settings screen). A single extension in the contacts package mirrors the existing Context.hasCalendarPermission() precedent; the settings call site follows in the settings cleanup commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,11 @@ interface ContactSpecialDatesDataSource {
|
|||||||
fun readSpecialDates(): List<ContactSpecialDate>
|
fun readSpecialDates(): List<ContactSpecialDate>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Whether `READ_CONTACTS` is granted — the gate for every contacts read. */
|
||||||
|
fun Context.hasContactsPermission(): Boolean =
|
||||||
|
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) ==
|
||||||
|
PackageManager.PERMISSION_GRANTED
|
||||||
|
|
||||||
/** Map a `ContactsContract` event `TYPE` to our calendar bucket. */
|
/** Map a `ContactsContract` event `TYPE` to our calendar bucket. */
|
||||||
internal fun specialDateTypeForRawEventType(type: Int): SpecialDateType = when (type) {
|
internal fun specialDateTypeForRawEventType(type: Int): SpecialDateType = when (type) {
|
||||||
Event.TYPE_BIRTHDAY -> SpecialDateType.Birthday
|
Event.TYPE_BIRTHDAY -> SpecialDateType.Birthday
|
||||||
@@ -40,9 +45,7 @@ class AndroidContactSpecialDatesDataSource @Inject constructor(
|
|||||||
@ApplicationContext private val context: Context,
|
@ApplicationContext private val context: Context,
|
||||||
) : ContactSpecialDatesDataSource {
|
) : ContactSpecialDatesDataSource {
|
||||||
|
|
||||||
override fun hasPermission(): Boolean =
|
override fun hasPermission(): Boolean = context.hasContactsPermission()
|
||||||
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) ==
|
|
||||||
PackageManager.PERMISSION_GRANTED
|
|
||||||
|
|
||||||
override fun readSpecialDates(): List<ContactSpecialDate> {
|
override fun readSpecialDates(): List<ContactSpecialDate> {
|
||||||
if (!hasPermission()) return emptyList()
|
if (!hasPermission()) return emptyList()
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
import de.jeanlucmakiola.calendula.data.contacts.SpecialDatesScheduler
|
import de.jeanlucmakiola.calendula.data.contacts.SpecialDatesScheduler
|
||||||
|
import de.jeanlucmakiola.calendula.data.contacts.hasContactsPermission
|
||||||
import de.jeanlucmakiola.calendula.ui.permission.PermissionScreen
|
import de.jeanlucmakiola.calendula.ui.permission.PermissionScreen
|
||||||
import de.jeanlucmakiola.calendula.ui.permission.ReminderOnboardingScreen
|
import de.jeanlucmakiola.calendula.ui.permission.ReminderOnboardingScreen
|
||||||
import de.jeanlucmakiola.calendula.ui.permission.ReminderOnboardingViewModel
|
import de.jeanlucmakiola.calendula.ui.permission.ReminderOnboardingViewModel
|
||||||
@@ -53,10 +54,7 @@ fun RootScreen(
|
|||||||
// Refresh the contact special-dates mirror on foreground (the
|
// Refresh the contact special-dates mirror on foreground (the
|
||||||
// worker is debounced and no-ops when the feature is off). Gated
|
// worker is debounced and no-ops when the feature is off). Gated
|
||||||
// on the permission so users without the opt-in never enqueue it.
|
// on the permission so users without the opt-in never enqueue it.
|
||||||
if (ContextCompat.checkSelfPermission(
|
if (context.hasContactsPermission()) {
|
||||||
context, Manifest.permission.READ_CONTACTS
|
|
||||||
) == PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
SpecialDatesScheduler.runNow(context, foreground = true)
|
SpecialDatesScheduler.runNow(context, foreground = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user