Explorar o código

kodein improvements

milan jurkulák %!s(int64=2) %!d(string=hai) anos
pai
achega
d32084d58f

+ 11 - 21
app/src/main/kotlin/org/mjdev/tvapp/ui/pages/MainPage.kt

@@ -9,7 +9,7 @@
 package org.mjdev.tvapp.ui.pages
 
 import android.annotation.SuppressLint
-import android.content.Context
+import android.content.ComponentName
 import android.net.Uri
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
@@ -25,17 +25,12 @@ import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.platform.LocalContext
-import org.kodein.di.DI
-import org.kodein.di.bind
-import org.kodein.di.singleton
 import org.mjdev.tvapp.BuildConfig
 import org.mjdev.tvapp.R
 import org.mjdev.tvapp.activity.IPTVActivity
 import org.mjdev.tvapp.activity.IPTVActivity.Companion.IPTV_DATA
+import org.mjdev.tvapp.activity.MainActivity
 import org.mjdev.tvapp.data.events.SyncEvent
-import org.mjdev.tvapp.database.DAO
-import org.mjdev.tvapp.module.ViewModelsModule
 import org.mjdev.tvapp.sync.SyncAdapter.Companion.pauseSync
 import org.mjdev.tvlib.data.local.User
 import org.mjdev.tvlib.auth.AuthManager.Companion.rememberAuthManager
@@ -59,16 +54,6 @@ import java.net.URL
 @SuppressLint("ComposableNaming")
 class MainPage : Page() {
 
-    // todo
-    @Suppress("MemberVisibilityCanBePrivate")
-    fun diMock(
-        context: Context
-    ) = DI.lazy(allowSilentOverride = true) {
-        bind<Context>() with singleton { context }
-        bind<DAO>() with singleton { DAO(context) }
-        import(ViewModelsModule)
-    }
-
     override val title: Int = R.string.title_home
     override val icon: ImageVector = Icons.Default.Home
 
@@ -77,9 +62,7 @@ class MainPage : Page() {
     @Composable
     override fun Content() {
         val navController = rememberNavControllerEx()
-        val viewModel: MainViewModel by rememberInstance {
-            diMock(LocalContext.current)
-        }
+        val viewModel: MainViewModel by rememberInstance()
         val syncEvents by observedEvents<SyncEvent>()
         // refresh every 32 items, todo improve
         val needRefresh by remember {
@@ -161,7 +144,14 @@ class MainPage : Page() {
                 },
                 customRows = mutableListOf<@Composable () -> Unit>().apply {
                     add {
-                        AppsRow()
+                        AppsRow(
+                            excludedActivities = listOf(
+                                ComponentName(
+                                    BuildConfig.APPLICATION_ID,
+                                    MainActivity::class.java.name
+                                )
+                            )
+                        )
                     }
                     if (viewModel.localAudioCursor.count > 0) add {
                         LocalAudioRow(

+ 11 - 0
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/DetailViewModel.kt

@@ -9,13 +9,17 @@
 package org.mjdev.tvapp.viewmodel
 
 import android.content.Context
+import org.kodein.di.DI
+import org.kodein.di.bind
 import org.kodein.di.instance
+import org.kodein.di.singleton
 import org.mjdev.tvapp.data.local.Media
 import org.mjdev.tvlib.helpers.cursor.AudioCursor
 import org.mjdev.tvlib.helpers.cursor.PhotoCursor
 import org.mjdev.tvlib.helpers.cursor.VideoCursor
 import org.mjdev.tvlib.viewmodel.BaseViewModel
 import org.mjdev.tvapp.database.DAO
+import org.mjdev.tvapp.module.MainModule
 import org.mjdev.tvlib.extensions.MediaItemExt.mediaItem
 import org.mjdev.tvlib.interfaces.ItemAudio
 import org.mjdev.tvlib.interfaces.ItemPhoto
@@ -53,4 +57,11 @@ class DetailViewModel(
         is Media -> getCachedList { dao.allMediaItems }
         else -> listOf(data.mediaItem)
     }
+
+    override fun mockDI(context: Context): DI = DI.lazy(allowSilentOverride = true) {
+        bind<Context>() with singleton { context }
+        bind<DAO>() with singleton { DAO(context) }
+        import(MainModule)
+    }
+
 }

+ 11 - 0
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/IPTVViewModel.kt

@@ -12,13 +12,17 @@ package org.mjdev.tvapp.viewmodel
 
 import android.content.Context
 import androidx.media3.common.MediaItem
+import org.kodein.di.DI
+import org.kodein.di.bind
 import org.kodein.di.instance
+import org.kodein.di.singleton
 import org.mjdev.tvapp.data.local.Media
 import org.mjdev.tvlib.helpers.cursor.AudioCursor
 import org.mjdev.tvlib.helpers.cursor.PhotoCursor
 import org.mjdev.tvlib.helpers.cursor.VideoCursor
 import org.mjdev.tvlib.viewmodel.BaseViewModel
 import org.mjdev.tvapp.database.DAO
+import org.mjdev.tvapp.module.MainModule
 import org.mjdev.tvlib.extensions.MediaItemExt.mediaItem
 import org.mjdev.tvlib.interfaces.ItemAudio
 import org.mjdev.tvlib.interfaces.ItemPhoto
@@ -63,4 +67,11 @@ class IPTVViewModel (
         }
         return cache[T::class] ?: emptyList()
     }
+
+    override fun mockDI(context: Context): DI = DI.lazy(allowSilentOverride = true) {
+        bind<Context>() with singleton { context }
+        bind<DAO>() with singleton { DAO(context) }
+        import(MainModule)
+    }
+
 }

+ 10 - 11
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/MainViewModel.kt

@@ -8,20 +8,21 @@
 
 package org.mjdev.tvapp.viewmodel
 
-import android.content.ComponentName
 import android.content.Context
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.channelFlow
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOn
+import org.kodein.di.DI
+import org.kodein.di.bind
 import org.kodein.di.instance
-import org.mjdev.tvapp.BuildConfig
-import org.mjdev.tvapp.activity.MainActivity
+import org.kodein.di.singleton
 import org.mjdev.tvlib.helpers.cursor.AudioCursor
 import org.mjdev.tvlib.helpers.cursor.PhotoCursor
 import org.mjdev.tvlib.helpers.cursor.VideoCursor
 import org.mjdev.tvlib.viewmodel.BaseViewModel
 import org.mjdev.tvapp.database.DAO
+import org.mjdev.tvapp.module.MainModule
 import org.mjdev.tvlib.extensions.ListExt.asMap
 import org.mjdev.tvlib.extensions.ListExt.takeIf
 import org.mjdev.tvlib.interfaces.ItemWithImage.Companion.hasImage
@@ -31,18 +32,10 @@ class MainViewModel(context: Context) : BaseViewModel(context) {
     @Suppress("PrivatePropertyName")
     private val ITEMS_FROM_CATEGORY = 3
 
-    private val excludedActivity = ComponentName(
-        BuildConfig.APPLICATION_ID,
-        MainActivity::class.java.name
-    )
-
     val dao: DAO by instance()
     val localAudioCursor: AudioCursor by instance()
     val localVideoCursor: VideoCursor by instance()
     val localPhotoCursor: PhotoCursor by instance()
-//    // todo : move to cursor
-//    val apps
-//        get() = appsManager(context, excludedActivity).stateInViewModel()
 
     // todo : move to cursor
     val messages
@@ -84,4 +77,10 @@ class MainViewModel(context: Context) : BaseViewModel(context) {
             emit(dao.countriesDao.all)
         }.flowOn(Dispatchers.IO).stateInViewModel()
 
+    override fun mockDI(context: Context): DI = DI.lazy(allowSilentOverride = true) {
+        bind<Context>() with singleton { context }
+        bind<DAO>() with singleton { DAO(context) }
+        import(MainModule)
+    }
+
 }

+ 2 - 1
documentation/release-notes-1.3.1.md

@@ -1,7 +1,8 @@
-## Release notes 1.0.0 - 14. 6. 2024, 12:16:16
+## Release notes 1.0.0 - 14. 6. 2024, 12:57:53
 
 * 14.06.2024
 
+* [milan jurkulák] : kodein improvements 
 * [milan jurkulák] : code cleanup 
 * [milan jurkulák] : code cleanup 
 

+ 5 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/AppsRow.kt

@@ -8,6 +8,7 @@
 
 package org.mjdev.tvlib.ui.components.tv
 
+import android.content.ComponentName
 import android.content.Context
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
@@ -40,7 +41,10 @@ fun AppsRow(
     startApp: Context.(app: App?) -> Unit = { app ->
         startActivity(app?.intent)
     },
-    apps: State<List<App>> = rememberAppsManager().collectAsState(emptyList()),
+    excludedActivities:List<ComponentName> = emptyList(),
+    apps: State<List<App>> = rememberAppsManager(
+        excluded = excludedActivities.toTypedArray()
+    ).collectAsState(emptyList()),
     cardWidth: Dp = computeCardWidth(3f)
 ) {
     val context: Context = LocalContext.current

+ 10 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/viewmodel/BaseViewModel.kt

@@ -8,10 +8,9 @@
 
 package org.mjdev.tvlib.viewmodel
 
-import android.app.Application
 import android.content.Context
-import androidx.lifecycle.AndroidViewModel
 import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
@@ -21,16 +20,17 @@ import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
 import kotlinx.coroutines.launch
+import org.kodein.di.DI
 import org.kodein.di.DIAware
 import timber.log.Timber
 
-@Suppress("unused", "StaticFieldLeak")
 open class BaseViewModel(
     context: Context
-) : AndroidViewModel(context.applicationContext as Application), DIAware {
+) : ViewModel(), DIAware {
 
-    override val di
-        get() = (getApplication() as DIAware).di
+    override val di by lazy {
+        if (context is DIAware) (context as DIAware).di else mockDI(context)
+    }
 
     val error: MutableStateFlow<Throwable?> = MutableStateFlow(null)
 
@@ -97,4 +97,8 @@ open class BaseViewModel(
         return result
     }
 
+    open fun mockDI(context: Context): DI {
+        throw (RuntimeException("No mocked DI defined. please override method mockDI()"))
+    }
+
 }