Compare commits

...

14 Commits

Author SHA1 Message Date
Arnau Mora
e9fb031d0a Upgrade dependencies
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-06-04 19:55:31 +02:00
Arnau Mora
d1c3548ccc Upgrade dependencies
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-06-04 19:54:46 +02:00
Arnau Mora
762095c7ce Merge branch 'main-ose' into nav3-migration
# Conflicts:
#	app/src/main/kotlin/at/bitfire/davdroid/db/AppDatabase.kt
#	app/src/main/kotlin/at/bitfire/davdroid/ui/AccountsScreen.kt
2025-06-04 19:53:43 +02:00
Arnau Mora
d9b36a0e34 Fix predictive back for drawer
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-27 15:21:23 +02:00
Arnau Mora
514623c0f2 Use ComponentActivity instead of AppCompatActivity
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-27 15:14:07 +02:00
Arnau Mora
9978850594 Moved nav back stack holding to viewmodel
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 20:07:50 +02:00
Arnau Mora
e1f5b2e3c1 Upgrade Activity Compose
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 20:06:49 +02:00
Arnau Mora
ad0cdb5c0c Use SDK 36
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:43:30 +02:00
Arnau Mora
de9d58bc20 Migrated AccountsActivity to MainActivity
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:36:11 +02:00
Arnau Mora
a6238a4131 Enable back invoked callback
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:35:27 +02:00
Arnau Mora
bbc7fbfa1e Added missing plugin
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:35:11 +02:00
Arnau Mora
3ba4dfb157 Upgrade Kotlin and KSP
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:35:01 +02:00
Arnau Mora
4544cd9b5c Fixed snapshot dependencies repository
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:34:05 +02:00
Arnau Mora
24026edad0 Added dependencies
Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2025-05-26 19:07:13 +02:00
16 changed files with 224 additions and 81 deletions

View File

@@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.mikepenz.aboutLibraries)
@@ -144,6 +145,9 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel.base)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.lifecycle.viewmodel.navigation3)
implementation(libs.androidx.navigation3.runtime)
implementation(libs.androidx.navigation3.ui)
implementation(libs.androidx.paging)
implementation(libs.androidx.paging.compose)
implementation(libs.androidx.preference)
@@ -154,6 +158,7 @@ dependencies {
implementation(libs.compose.accompanist.permissions)
implementation(platform(libs.compose.bom))
implementation(libs.compose.material3)
implementation(libs.compose.material3.navigation3)
implementation(libs.compose.materialIconsExtended)
debugImplementation(libs.compose.ui.tooling)
implementation(libs.compose.ui.toolingPreview)
@@ -177,6 +182,10 @@ dependencies {
implementation(libs.bitfire.ical4android)
implementation(libs.bitfire.vcard4android)
// Serialization (for navigation)
implementation(libs.kotlinx.serialization.core)
implementation(libs.kotlinx.serialization.json)
// third-party libs
@Suppress("RedundantSuppression")
implementation(libs.dnsjava)

View File

@@ -45,6 +45,7 @@
<application
android:name=".App"
android:allowBackup="false"
android:enableOnBackInvokedCallback="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
@@ -66,7 +67,7 @@
<activity android:name=".ui.intro.IntroActivity" />
<activity
android:name=".ui.AccountsActivity"
android:name=".ui.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
@@ -77,12 +78,12 @@
<activity
android:name=".ui.AboutActivity"
android:label="@string/navigation_drawer_about"
android:parentActivityName=".ui.AccountsActivity"/>
android:parentActivityName=".ui.MainActivity"/>
<activity
android:name=".ui.AppSettingsActivity"
android:label="@string/app_settings"
android:parentActivityName=".ui.AccountsActivity"
android:parentActivityName=".ui.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
@@ -110,7 +111,7 @@
<activity
android:name=".ui.setup.LoginActivity"
android:parentActivityName=".ui.AccountsActivity"
android:parentActivityName=".ui.MainActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
@@ -138,7 +139,7 @@
<activity
android:name=".ui.account.AccountActivity"
android:parentActivityName=".ui.AccountsActivity"
android:parentActivityName=".ui.MainActivity"
android:exported="true">
</activity>
<activity
@@ -160,7 +161,7 @@
<activity
android:name=".ui.webdav.WebdavMountsActivity"
android:exported="true"
android:parentActivityName=".ui.AccountsActivity" />
android:parentActivityName=".ui.MainActivity" />
<activity
android:name=".ui.webdav.AddWebdavMountActivity"
android:parentActivityName=".ui.webdav.WebdavMountsActivity"

View File

@@ -25,7 +25,7 @@ import at.bitfire.davdroid.TextTable
import at.bitfire.davdroid.db.migration.AutoMigration12
import at.bitfire.davdroid.db.migration.AutoMigration16
import at.bitfire.davdroid.db.migration.AutoMigration18
import at.bitfire.davdroid.ui.AccountsActivity
import at.bitfire.davdroid.ui.MainActivity
import at.bitfire.davdroid.ui.NotificationRegistry
import dagger.Module
import dagger.Provides
@@ -79,7 +79,7 @@ abstract class AppDatabase: RoomDatabase() {
.addCallback(object: Callback() {
override fun onDestructiveMigration(db: SupportSQLiteDatabase) {
notificationRegistry.notifyIfPossible(NotificationRegistry.NOTIFY_DATABASE_CORRUPTED) {
val launcherIntent = Intent(context, AccountsActivity::class.java)
val launcherIntent = Intent(context, MainActivity::class.java)
NotificationCompat.Builder(context, notificationRegistry.CHANNEL_GENERAL)
.setSmallIcon(R.drawable.ic_warning_notify)
.setContentTitle(context.getString(R.string.database_destructive_migration_title))

View File

@@ -1,58 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import at.bitfire.davdroid.ui.account.AccountActivity
import at.bitfire.davdroid.ui.intro.IntroActivity
import at.bitfire.davdroid.ui.setup.LoginActivity
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
class AccountsActivity: AppCompatActivity() {
@Inject
lateinit var accountsDrawerHandler: AccountsDrawerHandler
private val introActivityLauncher = registerForActivityResult(IntroActivity.Contract) { cancelled ->
if (cancelled)
finish()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// handle "Sync all" intent from launcher shortcut
val syncAccounts = intent.action == Intent.ACTION_SYNC
setContent {
AccountsScreen(
initialSyncAccounts = syncAccounts,
onShowAppIntro = {
introActivityLauncher.launch(null)
},
accountsDrawerHandler = accountsDrawerHandler,
onAddAccount = {
startActivity(Intent(this, LoginActivity::class.java))
},
onShowAccount = { account ->
val intent = Intent(this, AccountActivity::class.java)
intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account)
startActivity(intent)
},
onManagePermissions = {
startActivity(Intent(this, PermissionsActivity::class.java))
}
)
}
}
}

View File

@@ -54,6 +54,7 @@ import java.util.logging.Logger
class AccountsModel @AssistedInject constructor(
@Assisted private val syncAccountsOnInit: Boolean,
private val accountRepository: AccountRepository,
internal val accountsDrawerHandler: AccountsDrawerHandler,
@ApplicationContext private val context: Context,
private val db: AppDatabase,
introPageFactory: IntroPageFactory,

View File

@@ -9,6 +9,8 @@ import android.accounts.Account
import android.content.Intent
import android.os.Build
import android.provider.Settings
import androidx.activity.compose.LocalActivity
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
@@ -73,20 +75,50 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.ui.account.AccountActivity
import at.bitfire.davdroid.ui.account.AccountProgress
import at.bitfire.davdroid.ui.composable.ActionCard
import at.bitfire.davdroid.ui.composable.ProgressBar
import at.bitfire.davdroid.ui.intro.IntroActivity
import at.bitfire.davdroid.ui.setup.LoginActivity
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun AccountsScreen(initialSyncAccounts: Boolean) {
val context = LocalContext.current
val activity = LocalActivity.current
val introActivityLauncher = rememberLauncherForActivityResult(IntroActivity.Contract) { cancelled ->
if (cancelled) activity?.finish()
}
AccountsScreen(
initialSyncAccounts = initialSyncAccounts,
onShowAppIntro = {
introActivityLauncher.launch(null)
},
onAddAccount = {
context.startActivity(Intent(context, LoginActivity::class.java))
},
onShowAccount = { account ->
val intent = Intent(context, AccountActivity::class.java)
intent.putExtra(AccountActivity.EXTRA_ACCOUNT, account)
context.startActivity(intent)
},
onManagePermissions = {
context.startActivity(Intent(context, PermissionsActivity::class.java))
}
)
}
@Composable
fun AccountsScreen(
initialSyncAccounts: Boolean,
onShowAppIntro: () -> Unit,
accountsDrawerHandler: AccountsDrawerHandler,
onAddAccount: () -> Unit,
onShowAccount: (Account) -> Unit,
onManagePermissions: () -> Unit,
@@ -111,7 +143,7 @@ fun AccountsScreen(
}
AccountsScreen(
accountsDrawerHandler = accountsDrawerHandler,
accountsDrawerHandler = model.accountsDrawerHandler,
accounts = accounts,
showSyncAll = showSyncAll,
onSyncAll = { model.syncAllAccounts() },

View File

@@ -0,0 +1,31 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import at.bitfire.davdroid.ui.navigation.Destination
import at.bitfire.davdroid.ui.navigation.Navigation
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity: ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// handle "Sync all" intent from launcher shortcut
val syncAccounts = intent.action == Intent.ACTION_SYNC
setContent {
Navigation(
initialDestination = Destination.Accounts(syncAccounts),
)
}
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.ui.navigation.Destination
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit
class NavModel(
initialDestination: Destination,
) : ViewModel() {
private val _backStack = MutableStateFlow(listOf(initialDestination))
val backStack get() = _backStack.asStateFlow()
private val mutex = Semaphore(1)
/**
* Handles back navigation.
* @param amount The number of entries to pop from the end of the backstack, as calculated by the `NavDisplay`'s `sceneStrategy`.
*/
fun popBackStack(amount: Int) {
viewModelScope.launch {
mutex.withPermit {
val backStack = backStack.value.toMutableList().apply {
repeat(amount) { removeAt(lastIndex) }
}
_backStack.emit(backStack)
}
}
}
class Factory(
private val initialDestination: Destination = Destination.Accounts()
): ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return NavModel(initialDestination) as T
}
}
}

View File

@@ -86,7 +86,7 @@ object UiUtils {
ShortcutInfo.Builder(context, SHORTCUT_SYNC_ALL)
.setIcon(Icon.createWithResource(context, R.drawable.ic_sync_shortcut))
.setShortLabel(context.getString(R.string.accounts_sync_all))
.setIntent(Intent(Intent.ACTION_SYNC, null, context, AccountsActivity::class.java))
.setIntent(Intent(Intent.ACTION_SYNC, null, context, MainActivity::class.java))
.build()
)
} catch(e: Exception) {

View File

@@ -12,7 +12,7 @@ import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.IntentCompat
import at.bitfire.davdroid.R
import at.bitfire.davdroid.ui.AccountsActivity
import at.bitfire.davdroid.ui.MainActivity
import dagger.hilt.android.AndroidEntryPoint
import java.util.logging.Logger
import javax.inject.Inject
@@ -35,7 +35,7 @@ class AccountActivity : AppCompatActivity() {
logger.warning("AccountActivity requires EXTRA_ACCOUNT")
// Redirect to accounts overview activity
val intent = Intent(this, AccountsActivity::class.java).apply {
val intent = Intent(this, MainActivity::class.java).apply {
// Create a new root activity, do not allow going back.
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
}

View File

@@ -0,0 +1,9 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.navigation
sealed interface Destination {
data class Accounts(val syncAccounts: Boolean = false): Destination
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.navigation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator
import androidx.navigation3.runtime.entry
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberSavedStateNavEntryDecorator
import androidx.navigation3.ui.NavDisplay
import androidx.navigation3.ui.rememberSceneSetupNavEntryDecorator
import at.bitfire.davdroid.ui.AccountsScreen
import at.bitfire.davdroid.ui.NavModel
@Composable
fun Navigation(
initialDestination: Destination = Destination.Accounts(),
model: NavModel = viewModel(factory = NavModel.Factory(initialDestination)),
) {
val backStack by model.backStack.collectAsState()
NavDisplay(
backStack = backStack,
onBack = model::popBackStack,
entryDecorators = listOf(
// Add the default decorators for managing scenes and saving state
rememberSceneSetupNavEntryDecorator(),
rememberSavedStateNavEntryDecorator(),
// Then add the view model store decorator
rememberViewModelStoreNavEntryDecorator(),
),
entryProvider = entryProvider {
entry<Destination.Accounts> { key ->
AccountsScreen(
initialSyncAccounts = key.syncAccounts,
)
}
},
)
}

View File

@@ -4,13 +4,12 @@
package at.bitfire.davdroid.di
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory
import at.bitfire.davdroid.ui.AboutActivity
import at.bitfire.davdroid.ui.AccountsDrawerHandler
import at.bitfire.davdroid.ui.OpenSourceLicenseInfoProvider
import at.bitfire.davdroid.ui.OseAccountsDrawerHandler
import at.bitfire.davdroid.ui.intro.IntroPageFactory
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
import dagger.Binds
@@ -25,9 +24,6 @@ interface OseModules {
@Module
@InstallIn(ActivityComponent::class)
interface ForActivities {
@Binds
fun accountsDrawerHandler(impl: OseAccountsDrawerHandler): AccountsDrawerHandler
@Binds
fun loginTypesProvider(impl: StandardLoginTypesProvider): LoginTypesProvider
}
@@ -35,6 +31,9 @@ interface OseModules {
@Module
@InstallIn(ViewModelComponent::class)
interface ForViewModels {
@Binds
fun accountsDrawerHandler(impl: OseAccountsDrawerHandler): AccountsDrawerHandler
@Binds
fun appLicenseInfoProvider(impl: OpenSourceLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider

View File

@@ -7,6 +7,7 @@ plugins {
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.kotlin.serialization) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.mikepenz.aboutLibraries) apply false

View File

@@ -3,16 +3,19 @@
[versions]
android-agp = "8.10.1"
android-desugaring = "2.1.5"
androidx-activityCompose = "1.10.1"
androidx-appcompat = "1.7.0"
androidx-activityCompose = "1.12.0-alpha02"
androidx-appcompat = "1.7.1"
androidx-arch = "2.2.0"
androidx-browser = "1.8.0"
androidx-core = "1.16.0"
androidx-hilt = "1.2.0"
androidx-lifecycle = "2.9.0"
androidx-nav3-core = "1.0.0-alpha03"
androidx-nav3-material = "1.0.0-SNAPSHOT"
androidx-nav3-lifecycle = "1.0.0-alpha01"
androidx-paging = "3.3.6"
androidx-preference = "1.2.1"
androidx-security = "1.1.0-alpha07"
androidx-security = "1.1.0-beta01"
androidx-test-core = "1.6.1"
androidx-test-runner = "1.6.2"
androidx-test-rules = "1.6.1"
@@ -29,10 +32,12 @@ glance = "1.1.1"
guava = "33.4.8-android"
hilt = "2.56.2"
# keep in sync with ksp version
kotlin = "2.1.20"
kotlin = "2.1.21"
kotlinx-coroutines = "1.10.2"
kotlinx-serialization = "2.1.21"
kotlinx-serializationCore = "1.8.1"
# see https://github.com/google/ksp/releases for version numbers
ksp = "2.1.20-2.0.0"
ksp = "2.1.21-2.0.1"
mikepenz-aboutLibraries = "12.1.2"
nsk90-kstatemachine = "0.33.0"
mockk = "1.14.2"
@@ -60,6 +65,9 @@ androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "androi
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-base = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
androidx-lifecycle-viewmodel-navigation3 = { module = "androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "androidx-nav3-lifecycle" }
androidx-navigation3-runtime = { module = "androidx.navigation3:navigation3-runtime", version.ref = "androidx-nav3-core" }
androidx-navigation3-ui = { module = "androidx.navigation3:navigation3-ui", version.ref = "androidx-nav3-core" }
androidx-paging = { module = "androidx.paging:paging-runtime-ktx", version.ref = "androidx-paging" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "androidx-paging" }
androidx-preference = { module = "androidx.preference:preference-ktx", version.ref = "androidx-preference" }
@@ -79,6 +87,7 @@ commons-lang = { module = "org.apache.commons:commons-lang3", version.ref = "com
compose-accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "compose-accompanist" }
compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose-bom" }
compose-material3 = { group = "androidx.compose.material3", name = "material3" }
compose-material3-navigation3 = { group = "androidx.compose.material3.adaptive", name = "adaptive-navigation3", version.ref = "androidx-nav3-material" }
compose-materialIconsExtended = { module = "androidx.compose.material:material-icons-extended" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
compose-ui-toolingPreview = { module = "androidx.compose.ui:ui-tooling-preview" }
@@ -93,6 +102,8 @@ junit = { module = "junit:junit", version = "4.13.2" }
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlinx-serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinx-serializationCore" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serializationCore" }
mikepenz-aboutLibraries = { module = "com.mikepenz:aboutlibraries-compose-m3", version.ref = "mikepenz-aboutLibraries" }
mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
mockk-android = { module = "io.mockk:mockk-android", version.ref = "mockk" }
@@ -115,5 +126,6 @@ android-application = { id = "com.android.application", version.ref = "android-a
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinx-serialization"}
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
mikepenz-aboutLibraries = { id = "com.mikepenz.aboutlibraries.plugin", version.ref = "mikepenz-aboutLibraries" }

View File

@@ -1,3 +1,7 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
pluginManagement {
repositories {
google()
@@ -16,6 +20,13 @@ dependencyResolutionManagement {
// AppIntro, dav4jvm
maven("https://jitpack.io")
// To use ViewModel and Material 3 with Nav3
// See: https://developer.android.com/guide/navigation/navigation-3/get-started#artifacts
maven {
// View latest build id here: https://androidx.dev/snapshots/builds
url = uri("https://androidx.dev/snapshots/builds/13550935/artifacts/repository")
}
}
}