Provide a widget option (#643)

* Added Glance dependency

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

* Defined Glance widget

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

* Replaced with new worker

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

* Rename ui/widget to ui/composable, move sync widget into ui/widget; adapt strings

---------

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
This commit is contained in:
Arnau Mora 2024-03-20 12:37:57 +01:00 committed by GitHub
parent c3bf95fa5c
commit 28ddf5c86a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 174 additions and 34 deletions

View file

@ -179,6 +179,10 @@ dependencies {
debugImplementation(libs.compose.ui.tooling) debugImplementation(libs.compose.ui.tooling)
implementation(libs.compose.ui.toolingPreview) implementation(libs.compose.ui.toolingPreview)
// Glance Widgets
implementation(libs.glance.base)
implementation(libs.glance.material)
// Jetpack Room // Jetpack Room
implementation(libs.room.runtime) implementation(libs.room.runtime)
implementation(libs.room.base) implementation(libs.room.base)

View file

@ -295,6 +295,18 @@
android:resource="@xml/debug_paths" /> android:resource="@xml/debug_paths" />
</provider> </provider>
<!-- Widgets -->
<receiver android:name=".ui.widget.SyncButtonWidgetReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info_sync_button" />
</receiver>
</application> </application>
<!-- package visiblity which apps do we need to see? --> <!-- package visiblity which apps do we need to see? -->

View file

@ -53,7 +53,7 @@ import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.Constants.withStatParams import at.bitfire.davdroid.Constants.withStatParams
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.ui.widget.PixelBoxes import at.bitfire.davdroid.ui.composable.PixelBoxes
import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer
import com.mikepenz.aboutlibraries.util.withJson import com.mikepenz.aboutlibraries.util.withJson

View file

@ -89,7 +89,7 @@ import at.bitfire.davdroid.syncadapter.SyncUtils
import at.bitfire.davdroid.ui.account.AccountActivity import at.bitfire.davdroid.ui.account.AccountActivity
import at.bitfire.davdroid.ui.intro.IntroActivity import at.bitfire.davdroid.ui.intro.IntroActivity
import at.bitfire.davdroid.ui.setup.LoginActivity import at.bitfire.davdroid.ui.setup.LoginActivity
import at.bitfire.davdroid.ui.widget.ActionCard import at.bitfire.davdroid.ui.composable.ActionCard
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState import com.google.accompanist.permissions.rememberPermissionState

View file

@ -67,11 +67,11 @@ import at.bitfire.davdroid.settings.Settings
import at.bitfire.davdroid.settings.SettingsManager import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.intro.BatteryOptimizationsPage import at.bitfire.davdroid.ui.intro.BatteryOptimizationsPage
import at.bitfire.davdroid.ui.intro.OpenSourcePage import at.bitfire.davdroid.ui.intro.OpenSourcePage
import at.bitfire.davdroid.ui.widget.EditTextInputDialog import at.bitfire.davdroid.ui.composable.EditTextInputDialog
import at.bitfire.davdroid.ui.widget.MultipleChoiceInputDialog import at.bitfire.davdroid.ui.composable.MultipleChoiceInputDialog
import at.bitfire.davdroid.ui.widget.Setting import at.bitfire.davdroid.ui.composable.Setting
import at.bitfire.davdroid.ui.widget.SettingsHeader import at.bitfire.davdroid.ui.composable.SettingsHeader
import at.bitfire.davdroid.ui.widget.SwitchSetting import at.bitfire.davdroid.ui.composable.SwitchSetting
import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.davdroid.util.TaskUtils import at.bitfire.davdroid.util.TaskUtils
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider

View file

@ -83,7 +83,7 @@ import at.bitfire.davdroid.resource.LocalAddressBook
import at.bitfire.davdroid.settings.AccountSettings import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.settings.SettingsManager import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.syncadapter.BaseSyncWorker import at.bitfire.davdroid.syncadapter.BaseSyncWorker
import at.bitfire.davdroid.ui.widget.CardWithImage import at.bitfire.davdroid.ui.composable.CardWithImage
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import at.bitfire.ical4android.TaskProvider.ProviderName import at.bitfire.ical4android.TaskProvider.ProviderName
import at.techbee.jtx.JtxContract import at.techbee.jtx.JtxContract

View file

@ -39,8 +39,8 @@ import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.PackageChangedReceiver import at.bitfire.davdroid.PackageChangedReceiver
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.ui.widget.CardWithImage import at.bitfire.davdroid.ui.composable.CardWithImage
import at.bitfire.davdroid.ui.widget.PermissionSwitchRow import at.bitfire.davdroid.ui.composable.PermissionSwitchRow
import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import java.util.logging.Level import java.util.logging.Level

View file

@ -54,8 +54,8 @@ import at.bitfire.davdroid.R
import at.bitfire.davdroid.util.TaskUtils import at.bitfire.davdroid.util.TaskUtils
import at.bitfire.davdroid.settings.SettingsManager import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
import at.bitfire.davdroid.ui.widget.CardWithImage import at.bitfire.davdroid.ui.composable.CardWithImage
import at.bitfire.davdroid.ui.widget.RadioWithSwitch import at.bitfire.davdroid.ui.composable.RadioWithSwitch
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel

View file

@ -2,11 +2,15 @@ package at.bitfire.davdroid.ui
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.platform.LocalUriHandler
import at.bitfire.davdroid.ui.widget.SafeAndroidUriHandler import at.bitfire.davdroid.ui.composable.SafeAndroidUriHandler
import com.google.accompanist.themeadapter.material.MdcTheme import com.google.accompanist.themeadapter.material.MdcTheme
val primaryGreen = Color(0xff7cb342)
val onPrimaryGreen = Color(0xfffafafa)
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
@Composable @Composable
fun AppTheme(content: @Composable () -> Unit) { fun AppTheme(content: @Composable () -> Unit) {

View file

@ -81,7 +81,7 @@ import at.bitfire.davdroid.settings.AccountSettings
import at.bitfire.davdroid.syncadapter.OneTimeSyncWorker import at.bitfire.davdroid.syncadapter.OneTimeSyncWorker
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.PermissionsActivity import at.bitfire.davdroid.ui.PermissionsActivity
import at.bitfire.davdroid.ui.widget.ActionCard import at.bitfire.davdroid.ui.composable.ActionCard
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState import com.google.accompanist.permissions.rememberMultiplePermissionsState
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint

View file

@ -69,12 +69,12 @@ import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.syncadapter.OneTimeSyncWorker import at.bitfire.davdroid.syncadapter.OneTimeSyncWorker
import at.bitfire.davdroid.syncadapter.Syncer import at.bitfire.davdroid.syncadapter.Syncer
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.widget.ActionCard import at.bitfire.davdroid.ui.composable.ActionCard
import at.bitfire.davdroid.ui.widget.EditTextInputDialog import at.bitfire.davdroid.ui.composable.EditTextInputDialog
import at.bitfire.davdroid.ui.widget.MultipleChoiceInputDialog import at.bitfire.davdroid.ui.composable.MultipleChoiceInputDialog
import at.bitfire.davdroid.ui.widget.Setting import at.bitfire.davdroid.ui.composable.Setting
import at.bitfire.davdroid.ui.widget.SettingsHeader import at.bitfire.davdroid.ui.composable.SettingsHeader
import at.bitfire.davdroid.ui.widget.SwitchSetting import at.bitfire.davdroid.ui.composable.SwitchSetting
import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.davdroid.util.PermissionUtils
import at.bitfire.ical4android.TaskProvider import at.bitfire.ical4android.TaskProvider
import at.bitfire.vcard4android.GroupMethod import at.bitfire.vcard4android.GroupMethod

View file

@ -56,7 +56,7 @@ import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.Constants.withStatParams import at.bitfire.davdroid.Constants.withStatParams
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.widget.PermissionSwitchRow import at.bitfire.davdroid.ui.composable.PermissionSwitchRow
import at.bitfire.davdroid.util.PermissionUtils import at.bitfire.davdroid.util.PermissionUtils
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import android.text.method.LinkMovementMethod import android.text.method.LinkMovementMethod
import android.widget.AutoCompleteTextView import android.widget.AutoCompleteTextView

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import android.content.Context import android.content.Context
import android.graphics.Matrix import android.graphics.Matrix

View file

@ -1,4 +1,4 @@
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column

View file

@ -1,4 +1,4 @@
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding

View file

@ -1,4 +1,4 @@
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row

View file

@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details. * Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/ **************************************************************************************************/
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column

View file

@ -1,4 +1,4 @@
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import android.content.Context import android.content.Context
import android.widget.Toast import android.widget.Toast

View file

@ -1,4 +1,4 @@
package at.bitfire.davdroid.ui.widget package at.bitfire.davdroid.ui.composable
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box

View file

@ -39,7 +39,7 @@ import at.bitfire.davdroid.Constants
import at.bitfire.davdroid.Constants.withStatParams import at.bitfire.davdroid.Constants.withStatParams
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.settings.SettingsManager import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.widget.CardWithImage import at.bitfire.davdroid.ui.composable.CardWithImage
import dagger.hilt.EntryPoint import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors import dagger.hilt.android.EntryPointAccessors

View file

@ -60,7 +60,7 @@ import at.bitfire.davdroid.db.WebDavMount
import at.bitfire.davdroid.log.Logger import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.network.HttpClient import at.bitfire.davdroid.network.HttpClient
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.widget.PasswordTextField import at.bitfire.davdroid.ui.composable.PasswordTextField
import at.bitfire.davdroid.webdav.CredentialsStore import at.bitfire.davdroid.webdav.CredentialsStore
import at.bitfire.davdroid.webdav.DavDocumentsProvider import at.bitfire.davdroid.webdav.DavDocumentsProvider
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint

View file

@ -0,0 +1,92 @@
package at.bitfire.davdroid.ui.widget
import android.accounts.AccountManager
import android.content.Context
import android.widget.Toast
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.glance.ColorFilter
import androidx.glance.GlanceId
import androidx.glance.GlanceModifier
import androidx.glance.Image
import androidx.glance.ImageProvider
import androidx.glance.LocalContext
import androidx.glance.action.clickable
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.cornerRadius
import androidx.glance.appwidget.provideContent
import androidx.glance.background
import androidx.glance.layout.Alignment
import androidx.glance.layout.Row
import androidx.glance.layout.fillMaxWidth
import androidx.glance.layout.padding
import androidx.glance.layout.size
import androidx.glance.text.Text
import androidx.glance.text.TextDefaults
import androidx.glance.unit.ColorProvider
import at.bitfire.davdroid.R
import at.bitfire.davdroid.syncadapter.OneTimeSyncWorker
import at.bitfire.davdroid.ui.onPrimaryGreen
import at.bitfire.davdroid.ui.primaryGreen
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SyncButtonWidget : GlanceAppWidget() {
override suspend fun provideGlance(context: Context, id: GlanceId) {
provideContent {
WidgetContent()
}
}
@Composable
private fun WidgetContent() {
val context = LocalContext.current
Row(
modifier = GlanceModifier
.fillMaxWidth()
.background(primaryGreen)
.cornerRadius(16.dp)
.padding(4.dp)
.clickable {
requestSync(context)
},
verticalAlignment = Alignment.CenterVertically
) {
Image(
provider = ImageProvider(R.drawable.ic_sync),
contentDescription = context.getString(R.string.widget_sync_all_accounts),
modifier = GlanceModifier
.padding(vertical = 8.dp, horizontal = 8.dp)
.size(32.dp),
colorFilter = ColorFilter.tint(ColorProvider(onPrimaryGreen))
)
Text(
text = context.getString(R.string.widget_sync_all),
modifier = GlanceModifier
.defaultWeight()
.padding(end = 8.dp),
style = TextDefaults.defaultTextStyle.copy(
color = ColorProvider(onPrimaryGreen),
fontSize = 16.sp
)
)
}
}
private fun requestSync(context: Context) = CoroutineScope(Dispatchers.IO).launch {
val accountType = context.getString(R.string.account_type)
val accounts = AccountManager.get(context).getAccountsByType(accountType)
for (account in accounts) {
OneTimeSyncWorker.enqueueAllAuthorities(context, account, manual = true)
}
withContext(Dispatchers.Main) {
Toast.makeText(context, R.string.sync_started, Toast.LENGTH_SHORT).show()
}
}
}

View file

@ -0,0 +1,8 @@
package at.bitfire.davdroid.ui.widget
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
class SyncButtonWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = SyncButtonWidget()
}

View file

@ -490,6 +490,10 @@
<string name="sync_invalid_task">Received invalid task from server</string> <string name="sync_invalid_task">Received invalid task from server</string>
<string name="sync_invalid_resources_ignoring">Ignoring one or more invalid resources</string> <string name="sync_invalid_resources_ignoring">Ignoring one or more invalid resources</string>
<!-- widgets -->
<string name="widget_sync_all">Sync all</string>
<string name="widget_sync_all_accounts">Sync all accounts</string>
<!-- cert4android --> <!-- cert4android -->
<string name="certificate_notification_connection_security">DAVx⁵: Connection security</string> <string name="certificate_notification_connection_security">DAVx⁵: Connection security</string>
<string name="trust_certificate_unknown_certificate_found">DAVx⁵ has encountered an unknown certificate. Do you want to trust it?</string> <string name="trust_certificate_unknown_certificate_found">DAVx⁵ has encountered an unknown certificate. Do you want to trust it?</string>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:initialLayout="@layout/glance_default_loading_layout"
android:minWidth="100dp"
android:minHeight="30dp"
android:targetCellWidth="1"
android:targetCellHeight="1"
android:maxResizeWidth="250dp"
android:maxResizeHeight="30dp"
android:resizeMode="horizontal"
tools:ignore="UnusedAttribute">
</appwidget-provider>

View file

@ -42,6 +42,7 @@ compose-bom = "2024.02.02"
compose-compiler = "1.5.8" compose-compiler = "1.5.8"
# don't update to dnsjava 3.x until API level 26 (Android 8) is the minimum API [https://github.com/bitfireAT/davx5/issues/453] # don't update to dnsjava 3.x until API level 26 (Android 8) is the minimum API [https://github.com/bitfireAT/davx5/issues/453]
dnsjava = "2.1.9" dnsjava = "2.1.9"
glance = "1.0.0"
hilt = "2.51" hilt = "2.51"
jaredrummler-colorpicker = "1.1.0" jaredrummler-colorpicker = "1.1.0"
# keep in sync with * app/build.gradle.kts composeOptions.kotlinCompilerExtensionVersion # keep in sync with * app/build.gradle.kts composeOptions.kotlinCompilerExtensionVersion
@ -103,6 +104,8 @@ compose-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
compose-ui-toolingPreview = { module = "androidx.compose.ui:ui-tooling-preview" } compose-ui-toolingPreview = { module = "androidx.compose.ui:ui-tooling-preview" }
dnsjava = { module = "dnsjava:dnsjava", version.ref = "dnsjava" } dnsjava = { module = "dnsjava:dnsjava", version.ref = "dnsjava" }
glance-base = { module = "androidx.glance:glance-appwidget", version.ref = "glance" }
glance-material = { module = "androidx.glance:glance-material", version.ref = "glance" }
hilt-android-base = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } hilt-android-base = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" } hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }