Use hiltViewModel for creating ViewModels with parameters in new Screen architecture (#776)

* Add hilt-navigation-compose dependency

* AccountScreen: use hiltViewModel

* Use hiltViewModel for CollectionScreen and CreateCollectionScreens
This commit is contained in:
Ricki Hirner 2024-05-03 14:46:46 +02:00 committed by GitHub
parent 9005121b52
commit e6eb90861e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 39 additions and 116 deletions

View file

@ -148,6 +148,7 @@ dependencies {
implementation(libs.androidx.constraintLayout) implementation(libs.androidx.constraintLayout)
implementation(libs.androidx.core) implementation(libs.androidx.core)
implementation(libs.androidx.fragment) implementation(libs.androidx.fragment)
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.androidx.hilt.work) implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel.base) implementation(libs.androidx.lifecycle.viewmodel.base)

View file

@ -10,20 +10,11 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
@AndroidEntryPoint @AndroidEntryPoint
class AccountActivity : AppCompatActivity() { class AccountActivity : AppCompatActivity() {
@EntryPoint
@InstallIn(ActivityComponent::class)
interface AccountScreenEntryPoint {
fun accountModelAssistedFactory(): AccountScreenModel.Factory
}
companion object { companion object {
const val EXTRA_ACCOUNT = "account" const val EXTRA_ACCOUNT = "account"
} }

View file

@ -1,7 +1,6 @@
import android.Manifest import android.Manifest
import android.accounts.Account import android.accounts.Account
import android.app.Activity
import android.content.Intent import android.content.Intent
import android.net.Uri import android.net.Uri
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
@ -61,8 +60,8 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.LazyPagingItems
import androidx.paging.compose.collectAsLazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
@ -70,7 +69,6 @@ import at.bitfire.davdroid.db.Collection
import at.bitfire.davdroid.settings.AccountSettings import at.bitfire.davdroid.settings.AccountSettings
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.account.AccountActivity
import at.bitfire.davdroid.ui.account.AccountProgress import at.bitfire.davdroid.ui.account.AccountProgress
import at.bitfire.davdroid.ui.account.AccountScreenModel import at.bitfire.davdroid.ui.account.AccountScreenModel
import at.bitfire.davdroid.ui.account.CollectionsList import at.bitfire.davdroid.ui.account.CollectionsList
@ -79,7 +77,6 @@ import at.bitfire.davdroid.ui.composable.ActionCard
import at.bitfire.davdroid.util.TaskUtils import at.bitfire.davdroid.util.TaskUtils
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.EntryPointAccessors
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
@ -92,16 +89,17 @@ fun AccountScreen(
onNavUp: () -> Unit, onNavUp: () -> Unit,
onFinish: () -> Unit onFinish: () -> Unit
) { ) {
val context = LocalContext.current as Activity val model: AccountScreenModel = hiltViewModel(
val entryPoint = EntryPointAccessors.fromActivity(context, AccountActivity.AccountScreenEntryPoint::class.java) creationCallback = { factory: AccountScreenModel.Factory ->
val model = viewModel<AccountScreenModel>( factory.create(account)
factory = AccountScreenModel.factoryFromAccount(entryPoint.accountModelAssistedFactory(), account) }
) )
val addressBooksPager by model.addressBooksPager.collectAsState(null) val addressBooksPager by model.addressBooksPager.collectAsState(null)
val calendarsPager by model.calendarsPager.collectAsState(null) val calendarsPager by model.calendarsPager.collectAsState(null)
val subscriptionsPager by model.webcalPager.collectAsState(null) val subscriptionsPager by model.webcalPager.collectAsState(null)
val context = LocalContext.current
AccountScreen( AccountScreen(
accountName = account.name, accountName = account.name,
error = model.error, error = model.error,

View file

@ -30,6 +30,7 @@ import at.bitfire.davdroid.util.TaskUtils
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
@ -39,15 +40,16 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.logging.Level import java.util.logging.Level
@HiltViewModel(assistedFactory = AccountScreenModel.Factory::class)
class AccountScreenModel @AssistedInject constructor( class AccountScreenModel @AssistedInject constructor(
@Assisted val account: Account,
val context: Application, val context: Application,
private val accountRepository: AccountRepository, private val accountRepository: AccountRepository,
private val collectionRepository: DavCollectionRepository, private val collectionRepository: DavCollectionRepository,
serviceRepository: DavServiceRepository, serviceRepository: DavServiceRepository,
accountProgressUseCase: AccountProgressUseCase, accountProgressUseCase: AccountProgressUseCase,
getBindableHomesetsFromServiceUseCase: GetBindableHomeSetsFromServiceUseCase, getBindableHomesetsFromServiceUseCase: GetBindableHomeSetsFromServiceUseCase,
getServiceCollectionPagerUseCase: GetServiceCollectionPagerUseCase, getServiceCollectionPagerUseCase: GetServiceCollectionPagerUseCase
@Assisted val account: Account
): ViewModel() { ): ViewModel() {
@AssistedFactory @AssistedFactory
@ -55,15 +57,6 @@ class AccountScreenModel @AssistedInject constructor(
fun create(account: Account): AccountScreenModel fun create(account: Account): AccountScreenModel
} }
companion object {
fun factoryFromAccount(assistedFactory: Factory, account: Account) = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return assistedFactory.create(account) as T
}
}
}
/** whether the account is invalid and the screen shall be closed */ /** whether the account is invalid and the screen shall be closed */
val invalidAccount = accountRepository.getAllFlow().map { accounts -> val invalidAccount = accountRepository.getAllFlow().map { accounts ->
!accounts.contains(account) !accounts.contains(account)

View file

@ -10,20 +10,11 @@ import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
@AndroidEntryPoint @AndroidEntryPoint
class CollectionActivity: AppCompatActivity() { class CollectionActivity: AppCompatActivity() {
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CollectionEntryPoint {
fun collectionModelAssistedFactory(): CollectionScreenModel.Factory
}
companion object { companion object {
const val EXTRA_ACCOUNT = "account" const val EXTRA_ACCOUNT = "account"
const val EXTRA_COLLECTION_ID = "collection_id" const val EXTRA_COLLECTION_ID = "collection_id"

View file

@ -4,7 +4,6 @@
package at.bitfire.davdroid.ui.account package at.bitfire.davdroid.ui.account
import android.app.Activity
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -21,7 +20,6 @@ import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.AccountBox import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.CloudSync import androidx.compose.material.icons.filled.CloudSync
import androidx.compose.material.icons.filled.DeleteForever import androidx.compose.material.icons.filled.DeleteForever
import androidx.compose.material.icons.filled.DoNotDisturbOn import androidx.compose.material.icons.filled.DoNotDisturbOn
@ -47,19 +45,17 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.repository.DavSyncStatsRepository import at.bitfire.davdroid.repository.DavSyncStatsRepository
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog
import dagger.hilt.android.EntryPointAccessors
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -72,10 +68,10 @@ fun CollectionScreen(
onFinish: () -> Unit, onFinish: () -> Unit,
onNavUp: () -> Unit onNavUp: () -> Unit
) { ) {
val context = LocalContext.current as Activity val model: CollectionScreenModel = hiltViewModel(
val entryPoint = EntryPointAccessors.fromActivity(context, CollectionActivity.CollectionEntryPoint::class.java) creationCallback = { factory: CollectionScreenModel.Factory ->
val model = viewModel<CollectionScreenModel>( factory.create(collectionId)
factory = CollectionScreenModel.factoryFromCollection(entryPoint.collectionModelAssistedFactory(), collectionId) }
) )
val collectionOrNull by model.collection.collectAsStateWithLifecycle(null) val collectionOrNull by model.collection.collectAsStateWithLifecycle(null)

View file

@ -8,7 +8,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import at.bitfire.davdroid.db.AppDatabase import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.repository.DavCollectionRepository import at.bitfire.davdroid.repository.DavCollectionRepository
@ -17,6 +16,7 @@ import at.bitfire.davdroid.util.lastSegment
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@HiltViewModel(assistedFactory = CollectionScreenModel.Factory::class)
class CollectionScreenModel @AssistedInject constructor( class CollectionScreenModel @AssistedInject constructor(
@Assisted val collectionId: Long, @Assisted val collectionId: Long,
db: AppDatabase, db: AppDatabase,
@ -37,15 +38,6 @@ class CollectionScreenModel @AssistedInject constructor(
fun create(collectionId: Long): CollectionScreenModel fun create(collectionId: Long): CollectionScreenModel
} }
companion object {
fun factoryFromCollection(assistedFactory: Factory, collectionId: Long) = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return assistedFactory.create(collectionId) as T
}
}
}
var invalid by mutableStateOf(false) var invalid by mutableStateOf(false)
val collection = collectionRepository.getFlow(collectionId) val collection = collectionRepository.getFlow(collectionId)
.map { .map {

View file

@ -10,20 +10,11 @@ import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
@AndroidEntryPoint @AndroidEntryPoint
class CreateAddressBookActivity: AppCompatActivity() { class CreateAddressBookActivity: AppCompatActivity() {
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CreateAddressBookEntryPoint {
fun createAddressBookModelAssistedFactory(): CreateAddressBookModel.Factory
}
companion object { companion object {
const val EXTRA_ACCOUNT = "account" const val EXTRA_ACCOUNT = "account"
} }

View file

@ -9,21 +9,22 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import at.bitfire.davdroid.db.HomeSet import at.bitfire.davdroid.db.HomeSet
import at.bitfire.davdroid.repository.DavCollectionRepository import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.repository.DavHomeSetRepository import at.bitfire.davdroid.repository.DavHomeSetRepository
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@HiltViewModel(assistedFactory = CreateAddressBookModel.Factory::class)
class CreateAddressBookModel @AssistedInject constructor( class CreateAddressBookModel @AssistedInject constructor(
@Assisted val account: Account,
private val collectionRepository: DavCollectionRepository, private val collectionRepository: DavCollectionRepository,
homeSetRepository: DavHomeSetRepository, homeSetRepository: DavHomeSetRepository
@Assisted val account: Account
): ViewModel() { ): ViewModel() {
@AssistedFactory @AssistedFactory
@ -31,16 +32,6 @@ class CreateAddressBookModel @AssistedInject constructor(
fun create(account: Account): CreateAddressBookModel fun create(account: Account): CreateAddressBookModel
} }
companion object {
fun factoryFromAccount(assistedFactory: Factory, account: Account) = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return assistedFactory.create(account) as T
}
}
}
val addressBookHomeSets = homeSetRepository.getAddressBookHomeSetsFlow(account) val addressBookHomeSets = homeSetRepository.getAddressBookHomeSetsFlow(account)

View file

@ -5,7 +5,6 @@
package at.bitfire.davdroid.ui.account package at.bitfire.davdroid.ui.account
import android.accounts.Account import android.accounts.Account
import android.app.Activity
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
@ -31,18 +30,16 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.db.HomeSet import at.bitfire.davdroid.db.HomeSet
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog
import dagger.hilt.android.EntryPointAccessors
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
@Composable @Composable
@ -51,10 +48,10 @@ fun CreateAddressBookScreen(
onNavUp: () -> Unit = {}, onNavUp: () -> Unit = {},
onFinish: () -> Unit = {} onFinish: () -> Unit = {}
) { ) {
val context = LocalContext.current as Activity val model: CreateAddressBookModel = hiltViewModel(
val entryPoint = EntryPointAccessors.fromActivity(context, CreateAddressBookActivity.CreateAddressBookEntryPoint::class.java) creationCallback = { factory: CreateAddressBookModel.Factory ->
val model = viewModel<CreateAddressBookModel>( factory.create(account)
factory = CreateAddressBookModel.factoryFromAccount(entryPoint.createAddressBookModelAssistedFactory(), account) }
) )
val uiState = model.uiState val uiState = model.uiState

View file

@ -11,20 +11,11 @@ import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.TaskStackBuilder import androidx.core.app.TaskStackBuilder
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
@AndroidEntryPoint @AndroidEntryPoint
class CreateCalendarActivity: AppCompatActivity() { class CreateCalendarActivity: AppCompatActivity() {
@EntryPoint
@InstallIn(ActivityComponent::class)
interface CreateCalendarEntryPoint {
fun createCalendarModelAssistedFactory(): CreateCalendarModel.Factory
}
companion object { companion object {
const val EXTRA_ACCOUNT = "account" const val EXTRA_ACCOUNT = "account"
} }

View file

@ -9,7 +9,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import at.bitfire.davdroid.db.HomeSet import at.bitfire.davdroid.db.HomeSet
import at.bitfire.davdroid.repository.DavCollectionRepository import at.bitfire.davdroid.repository.DavCollectionRepository
import at.bitfire.davdroid.repository.DavHomeSetRepository import at.bitfire.davdroid.repository.DavHomeSetRepository
@ -17,6 +16,7 @@ import at.bitfire.ical4android.Css3Color
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.SupervisorJob
@ -30,10 +30,11 @@ import java.time.format.TextStyle
import java.util.Locale import java.util.Locale
import java.util.TimeZone import java.util.TimeZone
@HiltViewModel(assistedFactory = CreateCalendarModel.Factory::class)
class CreateCalendarModel @AssistedInject constructor( class CreateCalendarModel @AssistedInject constructor(
@Assisted val account: Account,
private val collectionRepository: DavCollectionRepository, private val collectionRepository: DavCollectionRepository,
homeSetRepository: DavHomeSetRepository, homeSetRepository: DavHomeSetRepository
@Assisted val account: Account
): ViewModel() { ): ViewModel() {
@AssistedFactory @AssistedFactory
@ -41,16 +42,6 @@ class CreateCalendarModel @AssistedInject constructor(
fun create(account: Account): CreateCalendarModel fun create(account: Account): CreateCalendarModel
} }
companion object {
fun factoryFromAccount(assistedFactory: Factory, account: Account) = object : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return assistedFactory.create(account) as T
}
}
}
val calendarHomeSets = homeSetRepository.getCalendarHomeSetsFlow(account) val calendarHomeSets = homeSetRepository.getCalendarHomeSetsFlow(account)
data class TimeZoneInfo( data class TimeZoneInfo(

View file

@ -5,7 +5,6 @@
package at.bitfire.davdroid.ui.account package at.bitfire.davdroid.ui.account
import android.accounts.Account import android.accounts.Account
import android.app.Activity
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
@ -53,15 +52,14 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.R import at.bitfire.davdroid.R
import at.bitfire.davdroid.db.HomeSet import at.bitfire.davdroid.db.HomeSet
import at.bitfire.davdroid.ui.AppTheme import at.bitfire.davdroid.ui.AppTheme
import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog import at.bitfire.davdroid.ui.composable.ExceptionInfoDialog
import at.bitfire.davdroid.ui.widget.CalendarColorPickerDialog import at.bitfire.davdroid.ui.widget.CalendarColorPickerDialog
import at.bitfire.ical4android.Css3Color import at.bitfire.ical4android.Css3Color
import dagger.hilt.android.EntryPointAccessors
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
@Composable @Composable
@ -70,10 +68,10 @@ fun CreateCalendarScreen(
onFinish: () -> Unit, onFinish: () -> Unit,
onNavUp: () -> Unit onNavUp: () -> Unit
) { ) {
val context = LocalContext.current as Activity val model: CreateCalendarModel = hiltViewModel(
val entryPoint = EntryPointAccessors.fromActivity(context, CreateCalendarActivity.CreateCalendarEntryPoint::class.java) creationCallback = { factory: CreateCalendarModel.Factory ->
val model = viewModel<CreateCalendarModel>( factory.create(account)
factory = CreateCalendarModel.factoryFromAccount(entryPoint.createCalendarModelAssistedFactory(), account) }
) )
val uiState = model.uiState val uiState = model.uiState
@ -203,7 +201,8 @@ fun CreateCalendarScreen(
} }
.size(48.dp) .size(48.dp)
.semantics { .semantics {
contentDescription = context.getString(R.string.create_collection_color) contentDescription =
context.getString(R.string.create_collection_color)
} }
) )
if (showColorPicker) { if (showColorPicker) {

View file

@ -70,6 +70,7 @@ androidx-constraintLayout = { module = "androidx.constraintlayout:constraintlayo
androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" } androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-fragment = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx-fragment" } androidx-fragment = { module = "androidx.fragment:fragment-ktx", version.ref = "androidx-fragment" }
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "androidx-hilt" } androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "androidx-hilt" }
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "androidx-hilt" }
androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "androidx-hilt" } androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "androidx-hilt" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } 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-base = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "androidx-lifecycle" }