Răsfoiți Sursa

DI: Setup viewmodel injection

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 3 ani în urmă
părinte
comite
716dcfe01d

+ 10 - 4
app/src/main/java/com/nextcloud/talk/activities/SharedItemsActivity.kt

@@ -9,10 +9,12 @@ import androidx.lifecycle.ViewModelProvider
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.LinearLayoutManager
 import androidx.recyclerview.widget.RecyclerView
+import autodagger.AutoInjector
 import com.google.android.material.tabs.TabLayout
 import com.nextcloud.talk.R
 import com.nextcloud.talk.adapters.SharedItemsGridAdapter
 import com.nextcloud.talk.adapters.SharedItemsListAdapter
+import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.databinding.ActivitySharedItemsBinding
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.repositories.SharedItemType
@@ -21,14 +23,20 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CONVERSATION_NAME
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
 import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_USER_ENTITY
 import com.nextcloud.talk.viewmodels.SharedItemsViewModel
+import javax.inject.Inject
 
+@AutoInjector(NextcloudTalkApplication::class)
 class SharedItemsActivity : AppCompatActivity() {
 
+    @Inject
+    lateinit var viewModelFactory: ViewModelProvider.Factory
+
     private lateinit var binding: ActivitySharedItemsBinding
     private lateinit var viewModel: SharedItemsViewModel
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
+        NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
 
         val roomToken = intent.getStringExtra(KEY_ROOM_TOKEN)!!
         val conversationName = intent.getStringExtra(KEY_CONVERSATION_NAME)
@@ -52,10 +60,8 @@ class SharedItemsActivity : AppCompatActivity() {
         supportActionBar?.title = conversationName
         supportActionBar?.setDisplayHomeAsUpEnabled(true)
 
-        viewModel = ViewModelProvider(
-            this,
-            SharedItemsViewModel.Factory(userEntity, roomToken, SharedItemType.MEDIA)
-        ).get(SharedItemsViewModel::class.java)
+        viewModel = ViewModelProvider(this, viewModelFactory)[SharedItemsViewModel::class.java]
+        viewModel.initialize(userEntity, roomToken, SharedItemType.MEDIA)
 
         viewModel.sharedItemTypes.observe(this) {
             initTabs(it)

+ 5 - 1
app/src/main/java/com/nextcloud/talk/application/NextcloudTalkApplication.kt

@@ -55,7 +55,9 @@ import com.nextcloud.talk.components.filebrowser.webdav.DavUtils
 import com.nextcloud.talk.dagger.modules.BusModule
 import com.nextcloud.talk.dagger.modules.ContextModule
 import com.nextcloud.talk.dagger.modules.DatabaseModule
+import com.nextcloud.talk.dagger.modules.RepositoryModule
 import com.nextcloud.talk.dagger.modules.RestModule
+import com.nextcloud.talk.dagger.modules.ViewModelModule
 import com.nextcloud.talk.jobs.AccountRemovalWorker
 import com.nextcloud.talk.jobs.CapabilitiesWorker
 import com.nextcloud.talk.jobs.SignalingSettingsWorker
@@ -89,7 +91,9 @@ import javax.inject.Singleton
         DatabaseModule::class,
         RestModule::class,
         UserModule::class,
-        ArbitraryStorageModule::class
+        ArbitraryStorageModule::class,
+        ViewModelModule::class,
+        RepositoryModule::class
     ]
 )
 @Singleton

+ 35 - 0
app/src/main/java/com/nextcloud/talk/dagger/modules/RepositoryModule.kt

@@ -0,0 +1,35 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Álvaro Brey
+ * Copyright (C) 2022 Álvaro Brey
+ * Copyright (C) 2022 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.dagger.modules
+
+import com.nextcloud.talk.api.NcApi
+import com.nextcloud.talk.repositories.SharedItemsRepository
+import dagger.Module
+import dagger.Provides
+
+@Module
+class RepositoryModule {
+    @Provides
+    fun provideSharedItemsRepository(ncApi: NcApi): SharedItemsRepository {
+        return SharedItemsRepository(ncApi)
+    }
+}

+ 56 - 0
app/src/main/java/com/nextcloud/talk/dagger/modules/ViewModelModule.kt

@@ -0,0 +1,56 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Álvaro Brey
+ * Copyright (C) 2022 Álvaro Brey
+ * Copyright (C) 2022 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.dagger.modules
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.nextcloud.talk.viewmodels.SharedItemsViewModel
+import dagger.Binds
+import dagger.MapKey
+import dagger.Module
+import dagger.multibindings.IntoMap
+import javax.inject.Inject
+import javax.inject.Provider
+import kotlin.reflect.KClass
+
+class ViewModelFactory @Inject constructor(
+    private val viewModels: MutableMap<Class<out ViewModel>, Provider<ViewModel>>
+) : ViewModelProvider.Factory {
+    override fun <T : ViewModel> create(modelClass: Class<T>): T = viewModels[modelClass]?.get() as T
+}
+
+@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
+@Retention(AnnotationRetention.RUNTIME)
+@MapKey
+internal annotation class ViewModelKey(val value: KClass<out ViewModel>)
+
+@Module
+abstract class ViewModelModule {
+
+    @Binds
+    abstract fun bindViewModelFactory(factory: ViewModelFactory): ViewModelProvider.Factory
+
+    @Binds
+    @IntoMap
+    @ViewModelKey(SharedItemsViewModel::class)
+    abstract fun sharedItemsViewModel(viewModel: SharedItemsViewModel): ViewModel
+}

+ 1 - 11
app/src/main/java/com/nextcloud/talk/repositories/SharedItemsRepository.kt

@@ -1,10 +1,8 @@
 package com.nextcloud.talk.repositories
 
 import android.util.Log
-import autodagger.AutoInjector
 import com.nextcloud.talk.R
 import com.nextcloud.talk.api.NcApi
-import com.nextcloud.talk.application.NextcloudTalkApplication
 import com.nextcloud.talk.application.NextcloudTalkApplication.Companion.sharedApplication
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.models.json.chat.ChatShareOverall
@@ -14,15 +12,7 @@ import retrofit2.Response
 import java.util.Locale
 import javax.inject.Inject
 
-@AutoInjector(NextcloudTalkApplication::class)
-class SharedItemsRepository {
-
-    @Inject
-    lateinit var ncApi: NcApi
-
-    init {
-        sharedApplication!!.componentApplication.inject(this)
-    }
+class SharedItemsRepository @Inject constructor(private val ncApi: NcApi) {
 
     fun media(parameters: Parameters, type: SharedItemType): Observable<SharedMediaItems>? {
         return media(parameters, type, null)

+ 16 - 28
app/src/main/java/com/nextcloud/talk/viewmodels/SharedItemsViewModel.kt

@@ -4,7 +4,6 @@ import android.util.Log
 import androidx.lifecycle.LiveData
 import androidx.lifecycle.MutableLiveData
 import androidx.lifecycle.ViewModel
-import androidx.lifecycle.ViewModelProvider
 import com.nextcloud.talk.models.database.UserEntity
 import com.nextcloud.talk.repositories.SharedItemType
 import com.nextcloud.talk.repositories.SharedItemsRepository
@@ -13,11 +12,10 @@ import io.reactivex.Observer
 import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
+import javax.inject.Inject
 
-class SharedItemsViewModel(
-    private val repository: SharedItemsRepository,
-    private val initialType: SharedItemType,
-    private val repositoryParameters: SharedItemsRepository.Parameters
+class SharedItemsViewModel @Inject constructor(
+    private val repository: SharedItemsRepository
 ) :
     ViewModel() {
 
@@ -29,11 +27,12 @@ class SharedItemsViewModel(
 
     private val _sharedItems: MutableLiveData<SharedMediaItems> by lazy {
         MutableLiveData<SharedMediaItems>().also {
-            loadItems(initialType)
+            loadItems(_currentItemType)
         }
     }
 
-    private var _currentItemType = initialType
+    private lateinit var repositoryParameters: SharedItemsRepository.Parameters
+    private lateinit var _currentItemType: SharedItemType
 
     val sharedItemTypes: LiveData<Set<SharedItemType>>
         get() = _sharedItemTypes
@@ -120,27 +119,16 @@ class SharedItemsViewModel(
             })
     }
 
-    class Factory(val userEntity: UserEntity, val roomToken: String, private val initialType: SharedItemType) :
-        ViewModelProvider
-        .Factory {
-
-        override fun <T : ViewModel?> create(modelClass: Class<T>): T {
-            if (modelClass.isAssignableFrom(SharedItemsViewModel::class.java)) {
-
-                val repository = SharedItemsRepository()
-                val repositoryParameters = SharedItemsRepository.Parameters(
-                    userEntity.userId,
-                    userEntity.token,
-                    userEntity.baseUrl,
-                    userEntity,
-                    roomToken
-                )
-
-                return SharedItemsViewModel(repository, initialType, repositoryParameters) as T
-            }
-
-            throw IllegalArgumentException("Unknown ViewModel class")
-        }
+    // TODO cleanup
+    fun initialize(userEntity: UserEntity, roomToken: String, initialType: SharedItemType) {
+        repositoryParameters = SharedItemsRepository.Parameters(
+            userEntity.userId,
+            userEntity.token,
+            userEntity.baseUrl,
+            userEntity,
+            roomToken
+        )
+        _currentItemType = initialType
     }
 
     companion object {