Browse Source

code cleanup

Milan Jurkulak 3 năm trước cách đây
mục cha
commit
dc475c6f00
47 tập tin đã thay đổi với 256 bổ sung và 289 xóa
  1. 82 0
      .github/workflows/codeql.yml
  2. 0 2
      app/build.gradle.kts
  3. 2 1
      app/src/main/AndroidManifest.xml
  4. 0 1
      app/src/main/kotlin/org/mjdev/tvapp/data/local/Movie.kt
  5. 0 1
      app/src/main/kotlin/org/mjdev/tvapp/ui/pages/AboutPage.kt
  6. 9 11
      app/src/main/kotlin/org/mjdev/tvapp/ui/pages/MainPage.kt
  7. 16 12
      app/src/main/kotlin/org/mjdev/tvapp/viewmodel/MainViewModel.kt
  8. 3 3
      build.gradle.kts
  9. 0 2
      tvlib/build.gradle.kts
  10. 4 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/activity/ComposableActivity.kt
  11. 5 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/assets/AssetType.kt
  12. 50 44
      tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ComposeExt.kt
  13. 0 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ModifierExt.kt
  14. 6 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/NavExt.kt
  15. 1 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/cursor/CachingCursor.kt
  16. 0 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/ItemCard.kt
  17. 0 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/PhotoCard.kt
  18. 0 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/BigCarousel.kt
  19. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/Carousel.kt
  20. 0 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/CarouselCard.kt
  21. 0 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/gallery/Gallery.kt
  22. 0 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/gridview/TvGridView.kt
  23. 2 7
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/CircleImage.kt
  24. 1 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/FadingPhotoImage.kt
  25. 3 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageAny.kt
  26. 2 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageBackground.kt
  27. 9 12
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/PhotoImage.kt
  28. 0 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/NativePlayerImpl.kt
  29. 2 9
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavHostEx.kt
  30. 2 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/Navigation.kt
  31. 0 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/SettingsDrawer.kt
  32. 4 12
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/Page.kt
  33. 0 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/PagerScope.kt
  34. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/screen/ScreenView.kt
  35. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/AppsRow.kt
  36. 2 9
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/BrowseView.kt
  37. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CategoryRow.kt
  38. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CursorRow.kt
  39. 1 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Header.kt
  40. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalAudioRow.kt
  41. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalPhotosRow.kt
  42. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalVideoRow.kt
  43. 0 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Tabs.kt
  44. 1 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/UserPic.kt
  45. 27 31
      tvlib/src/main/kotlin/org/mjdev/tvlib/updater/AppUpdater.kt
  46. 8 7
      tvlib/src/main/kotlin/org/mjdev/tvlib/webclient/CustomWebViewClient.kt
  47. 6 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/webclient/html/HtmlElement.kt

+ 82 - 0
.github/workflows/codeql.yml

@@ -0,0 +1,82 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+  push:
+    branches: [ "main" ]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [ "main" ]
+  schedule:
+    - cron: '22 8 * * 5'
+
+jobs:
+  analyze:
+    name: Analyze
+    # Runner size impacts CodeQL analysis time. To learn more, please see:
+    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
+    #   - https://gh.io/supported-runners-and-hardware-resources
+    #   - https://gh.io/using-larger-runners
+    # Consider using larger runners for possible analysis time improvements.
+    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
+    timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
+    permissions:
+      actions: read
+      contents: read
+      security-events: write
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'java' ]
+        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby', 'swift' ]
+        # Use only 'java' to analyze code written in Java, Kotlin or both
+        # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
+        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v3
+
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v2
+      with:
+        languages: ${{ matrix.language }}
+        # If you wish to specify custom queries, you can do so here or in a config file.
+        # By default, queries listed here will override any specified in a config file.
+        # Prefix the list here with "+" to use these queries and those in the config file.
+
+        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
+        # queries: security-extended,security-and-quality
+
+
+    # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
+    # If this step fails, then you should remove it and run the build manually (see below)
+    - name: Autobuild
+      uses: github/codeql-action/autobuild@v2
+
+    # ℹ️ Command-line programs to run using the OS shell.
+    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
+
+    #   If the Autobuild fails above, remove it and uncomment the following three lines.
+    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
+
+    # - run: |
+    #     echo "Run, Build Application using script"
+    #     ./location_of_script_within_repo/buildscript.sh
+
+    - name: Perform CodeQL Analysis
+      uses: github/codeql-action/analyze@v2
+      with:
+        category: "/language:${{matrix.language}}"

+ 0 - 2
app/build.gradle.kts

@@ -6,8 +6,6 @@
  * w: https://mjdev.org
  */
 
-@file:Suppress("UnstableApiUsage")
-
 import org.mjdev.gradle.extensions.implementation
 import org.mjdev.gradle.extensions.kapt
 import org.mjdev.gradle.plugin.MainAppPlugin.Companion.javaVersion

+ 2 - 1
app/src/main/AndroidManifest.xml

@@ -173,7 +173,8 @@
         <service
             android:name=".sync.SyncService"
             android:process=":sync"
-            android:exported="true">
+            android:exported="true"
+            tools:ignore="ExportedService">
 
             <intent-filter>
                 <action android:name="android.content.SyncAdapter" />

+ 0 - 1
app/src/main/kotlin/org/mjdev/tvapp/data/local/Movie.kt

@@ -63,7 +63,6 @@ class Movie :
     @Json(name = "category")
     var category: String? = ""
         get() = (field ?: country)?.replaceFirstChar { ch ->
-            // todo : and
             ch.titlecase(Locale.ROOT)
         }
 

+ 0 - 1
app/src/main/kotlin/org/mjdev/tvapp/ui/pages/AboutPage.kt

@@ -68,7 +68,6 @@ class AboutPage : Page() {
                             modifier = Modifier.size(128.dp),
                             contentPadding = 10.dp,
                             src = R.drawable.milanj,
-                            imageLoader = imageLoader
                         )
                         CardContent(
                             modifier = Modifier.fillMaxWidth(),

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

@@ -36,6 +36,7 @@ import org.mjdev.tvlib.ui.components.tv.LocalPhotosRow
 import org.mjdev.tvlib.ui.components.tv.LocalVideoRow
 import org.mjdev.tvapp.viewmodel.MainViewModel
 import org.mjdev.tvlib.annotations.Previews
+import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.interfaces.ItemPhoto
 import org.mjdev.tvlib.interfaces.ItemWithBackground
 import org.mjdev.tvlib.interfaces.ItemWithImage
@@ -51,6 +52,8 @@ class MainPage : Page() {
     @Previews
     @Composable
     override fun Content() {
+        val navController = rememberNavControllerEx()
+
         val viewModel: MainViewModel = appViewModel { context ->
             MainViewModel.mock(context)
         }
@@ -67,10 +70,10 @@ class MainPage : Page() {
             val dataId = (item as? ItemWithId)?.id
             if (dataId != null) {
                 viewModel.findMovie(dataId) { movie ->
-                    navController?.startActivity<IPTVActivity>(IPTV_DATA to movie)
+                    navController.startActivity<IPTVActivity>(IPTV_DATA to movie)
                 }
             } else if (item is Serializable) {
-                navController?.startActivity<IPTVActivity>(IPTV_DATA to item)
+                navController.startActivity<IPTVActivity>(IPTV_DATA to item)
             }
         }
 
@@ -84,7 +87,7 @@ class MainPage : Page() {
                 is ItemWithImage<*> -> item.image
                 else -> item.toString()
             }.also { uri ->
-                navController?.backgroundState?.value = uri
+                navController.backgroundState.value = uri
             }
         }
 
@@ -112,14 +115,13 @@ class MainPage : Page() {
                 categoriesAndItemsMap = streamingData.value,
                 errorState = errorState,
                 onTitleClicked = {
-                    navController?.openMenu()
+                    navController.openMenu()
                 },
                 onItemFocused = onItemSelect,
                 onItemClicked = onItemClick,
-                imageLoader = imageLoader,
                 onUserPicClicked = {
                     if (authManager.isUserLoggedIn) {
-                        navController?.openSettings()
+                        navController.openSettings()
                     } else {
                         authManager.login()
                     }
@@ -127,8 +129,7 @@ class MainPage : Page() {
                 customRows = mutableListOf<@Composable () -> Unit>().apply {
                     add {
                         AppsRow(
-                            apps = apps,
-                            imageLoader = imageLoader
+                            apps = apps
                         )
                     }
                     if (viewModel.localAudioCursor.count > 0) add {
@@ -136,7 +137,6 @@ class MainPage : Page() {
                             cursor = viewModel.localAudioCursor,
                             openItem = { item -> onItemClick(item) },
                             onItemFocus = onItemSelect,
-                            imageLoader = imageLoader
                         )
                     }
                     if (viewModel.localVideoCursor.count > 0) add {
@@ -144,7 +144,6 @@ class MainPage : Page() {
                             cursor = viewModel.localVideoCursor,
                             openItem = { item -> onItemClick(item) },
                             onItemFocus = onItemSelect,
-                            imageLoader = imageLoader
                         )
                     }
                     if (viewModel.localPhotoCursor.count > 0) add {
@@ -152,7 +151,6 @@ class MainPage : Page() {
                             cursor = viewModel.localPhotoCursor,
                             openItem = { item -> onItemClick(item) },
                             onItemFocus = onItemSelect,
-                            imageLoader = imageLoader
                         )
                     }
                 }

+ 16 - 12
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/MainViewModel.kt

@@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.channelFlow
 import kotlinx.coroutines.flow.flow
 import org.mjdev.tvapp.BuildConfig
-import org.mjdev.tvapp.R
 import org.mjdev.tvapp.activity.MainActivity
 import org.mjdev.tvlib.extensions.ListExt.asMap
 import org.mjdev.tvlib.helpers.cursor.AudioCursor
@@ -48,9 +47,9 @@ class MainViewModel @Inject constructor(
     @Inject
     lateinit var localPhotoCursor: PhotoCursor
 
-    private val noCategoryString by lazy {
-        context.getString(R.string.title_no_category)
-    }
+//    private val noCategoryString by lazy {
+//        context.getString(R.string.title_no_category)
+//    }
 
     val apps = appsManager(
         context, ComponentName(
@@ -81,16 +80,21 @@ class MainViewModel @Inject constructor(
         }
     }.stateInViewModel()
 
-    // todo anr
     val movieList: StateFlow<Map<String, List<Movie>>> = flow {
         dao.movieDao.all
-            .sortedBy { m ->
-                m.category
-            }.asMap { m ->
-                Pair(m.category, m)
-            }.also { map ->
-                emit(map)
-            }
+// todo anr
+//            .map { movie ->
+//            movie.apply {
+//                category = category ?: noCategoryString
+//            }
+//        }
+        .sortedBy { m ->
+            m.category
+        }.asMap { m ->
+            Pair(m.category, m)
+        }.also { map ->
+            emit(map)
+        }
     }.stateInViewModel()
 
     val countryList: StateFlow<List<String>> = flow {

+ 3 - 3
build.gradle.kts

@@ -26,13 +26,13 @@ buildscript {
         classpath("com.android.tools:r8:8.1.56")
         classpath("io.objectbox:objectbox-gradle-plugin:3.6.0")
         classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")
-        classpath("com.android.tools.build:gradle:8.1.1")
-        classpath("com.android.tools.build:gradle-api:8.1.1")
+        classpath("com.android.tools.build:gradle:8.1.2")
+        classpath("com.android.tools.build:gradle-api:8.1.2")
 //        classpath("com.newrelic.agent.android:agent-gradle-plugin:5.9.0")
         classpath ("app.cash.paparazzi:paparazzi-gradle-plugin:1.3.1")
     }
 }
 
 tasks.register<Delete>("clean") {
-    delete(rootProject.buildDir)
+    delete(rootProject.layout.buildDirectory)
 }

+ 0 - 2
tvlib/build.gradle.kts

@@ -1,5 +1,3 @@
-@file:Suppress("UnstableApiUsage")
-
 import org.mjdev.gradle.extensions.implementation
 import org.mjdev.gradle.plugin.MainAppPlugin.Companion.javaVersion
 import org.mjdev.gradle.plugin.MainAppPlugin.Companion.kotlinCompilerExtVersion

+ 4 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/activity/ComposableActivity.kt

@@ -34,7 +34,7 @@ import coil.ImageLoader
 import com.github.anrwatchdog.ANRWatchDog
 import org.mjdev.tvlib.BuildConfig
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
+import org.mjdev.tvlib.extensions.ComposeExt.createImageLoader
 import org.mjdev.tvlib.extensions.ContextExt.isATv
 import org.mjdev.tvlib.extensions.ModifierExt.detectSwipe
 import org.mjdev.tvlib.extensions.NavExt.navControllerEx
@@ -78,9 +78,9 @@ open class ComposableActivity : ComponentActivity() {
             }
     }
 
-    val imageLoader: ImageLoader
-        @Composable
-        get() = rememberImageLoader()
+    val imageLoader: ImageLoader by lazy {
+        createImageLoader(this)
+    }
 
     @Previews
     @OptIn(ExperimentalTvMaterial3Api::class)
@@ -111,7 +111,6 @@ open class ComposableActivity : ComponentActivity() {
                     modifier = Modifier.fillMaxSize(),
                     navController = navController,
                     builder = navGraphBuilder,
-                    imageLoader = imageLoader
                 )
             }
         }

+ 5 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/assets/AssetType.kt

@@ -1,9 +1,12 @@
-package org.mjdev.tvlib.assets;
+package org.mjdev.tvlib.assets
 
 import java.io.File
 import kotlin.reflect.KClass
 
-enum class AssetType(val fileExt: String, val parserClass: KClass<*>) {
+enum class AssetType(
+    val fileExt: String,
+    val parserClass: KClass<*>
+) {
 
     UNKNOWN("", Unit::class),
     DIRECTORY("", Unit::class);

+ 50 - 44
tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ComposeExt.kt

@@ -12,6 +12,7 @@ package org.mjdev.tvlib.extensions
 
 import android.annotation.SuppressLint
 import android.content.ContentResolver
+import android.content.Context
 import android.content.res.Configuration
 import android.content.res.Resources
 import android.graphics.Bitmap
@@ -33,7 +34,6 @@ import androidx.compose.ui.platform.LocalInspectionMode
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.core.graphics.drawable.toDrawable
 import androidx.tv.material3.DrawerState
 import androidx.tv.material3.DrawerValue
 import androidx.tv.material3.ExperimentalTvMaterial3Api
@@ -48,6 +48,7 @@ import kotlinx.coroutines.CoroutineScope
 import okhttp3.Cache
 import okhttp3.OkHttpClient
 import okhttp3.logging.HttpLoggingInterceptor
+import org.mjdev.tvlib.activity.ComposableActivity
 import org.mjdev.tvlib.extensions.ContextExt.isATv
 import org.mjdev.tvlib.helpers.coil.AlbumArtDecoder
 import org.mjdev.tvlib.network.CacheInterceptor
@@ -183,50 +184,55 @@ object ComposeExt {
     @Composable
     fun rememberImageLoader(): ImageLoader {
         val context = LocalContext.current
-        return remember(context) {
-            ImageLoader.Builder(context)
-                .allowHardware(false)
-                .addLastModifiedToFileCacheKey(true)
-                .crossfade(false)
-                .diskCachePolicy(CachePolicy.ENABLED)
-                .memoryCachePolicy(CachePolicy.DISABLED)
-                .okHttpClient {
-                    OkHttpClient.Builder()
-                        .cache(
-                            Cache(
-                                directory = File(
-                                    context.applicationContext.cacheDir,
-                                    "http_cache"
-                                ),
-                                maxSize = 1024L * 1024L * 1024L
-                            )
-                        )
-                        .addNetworkInterceptor(HttpLoggingInterceptor().apply {
-                            level = HttpLoggingInterceptor.Level.BODY
-                        })
-                        .addNetworkInterceptor(CacheInterceptor())
-                        .build()
-                }
-                .diskCache {
-                    DiskCache.Builder()
-                        .directory(context.cacheDir.resolve("image_cache"))
-                        .maxSizePercent(0.7)
-                        .build()
-                }
-//                .respectCacheHeaders(false)
-//                .networkObserverEnabled(true)
-                .components {
-                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
-                        add(ImageDecoderDecoder.Factory())
-                    } else {
-                        add(GifDecoder.Factory())
-                    }
-                    add(AlbumArtDecoder.Factory())
-                    add(VideoFrameDecoder.Factory())
-                    add(SvgDecoder.Factory())
-                }
-                .build()
+        val activity = context as? ComposableActivity
+        val cachedImageLoader = activity?.imageLoader
+        return cachedImageLoader ?: remember(context) {
+            createImageLoader(context)
         }
     }
 
+    fun createImageLoader(context: Context) = ImageLoader.Builder(context)
+        .allowHardware(false)
+        .allowRgb565(true)
+        .addLastModifiedToFileCacheKey(false)
+        .crossfade(false)
+        .diskCachePolicy(CachePolicy.ENABLED)
+        .memoryCachePolicy(CachePolicy.DISABLED)
+        .respectCacheHeaders(false)
+        .networkObserverEnabled(true)
+        .okHttpClient {
+            OkHttpClient.Builder()
+                .cache(
+                    Cache(
+                        directory = File(
+                            context.applicationContext.cacheDir,
+                            "http_cache"
+                        ),
+                        maxSize = 1024L * 1024L * 1024L
+                    )
+                )
+                .addNetworkInterceptor(HttpLoggingInterceptor().apply {
+                    level = HttpLoggingInterceptor.Level.BODY
+                })
+                .addNetworkInterceptor(CacheInterceptor())
+                .build()
+        }
+        .diskCache {
+            DiskCache.Builder()
+                .directory(context.cacheDir.resolve("image_cache"))
+                .maxSizePercent(0.7)
+                .build()
+        }
+        .components {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+                add(ImageDecoderDecoder.Factory())
+            } else {
+                add(GifDecoder.Factory())
+            }
+            add(AlbumArtDecoder.Factory())
+            add(VideoFrameDecoder.Factory())
+            add(SvgDecoder.Factory())
+        }
+        .build()
+
 }

+ 0 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ModifierExt.kt

@@ -43,12 +43,10 @@ import androidx.compose.ui.graphics.lerp
 import androidx.compose.ui.input.pointer.PointerInputScope
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.onSizeChanged
-import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.delay
 import org.mjdev.tvlib.BuildConfig
-import org.mjdev.tvlib.R
 import org.mjdev.tvlib.extensions.ComposeExt.isLandscapeMode
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
 import timber.log.Timber
@@ -129,7 +127,6 @@ object ModifierExt {
         )
     }
 
-
     val isRecomposeHighlighterEnabled: Boolean
         @Composable
         get() = BuildConfig.RECOMPOSE_ENABLED

+ 6 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/NavExt.kt

@@ -19,6 +19,7 @@ import androidx.navigation.Navigator
 import androidx.navigation.NavigatorProvider
 import androidx.navigation.compose.ComposeNavigator
 import androidx.navigation.compose.DialogNavigator
+import org.mjdev.tvlib.activity.ComposableActivity
 import org.mjdev.tvlib.navigation.NavGraphBuilderEx
 import org.mjdev.tvlib.navigation.NavHostControllerEx
 
@@ -46,12 +47,15 @@ object NavExt {
         vararg navigators: Navigator<out NavDestination>
     ): NavHostControllerEx {
         val context = LocalContext.current
-        return rememberSaveable(
+        val activity = context as? ComposableActivity
+        val navigatorCached = activity?.navController
+        // todo navigators check
+        return (navigatorCached ?: rememberSaveable(
             inputs = arrayOf(context, navigators),
             saver = NavControllerSaver(context)
         ) {
             createNavController(context)
-        }.apply {
+        }).apply {
             for (navigator in navigators) {
                 navigatorProvider.addNavigator(navigator)
             }

+ 1 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/cursor/CachingCursor.kt

@@ -6,8 +6,6 @@
  *  w: https://mjdev.org
  */
 
-@file:Suppress("unused")
-
 package org.mjdev.tvlib.helpers.cursor
 
 import android.annotation.SuppressLint
@@ -34,7 +32,6 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
 import org.mjdev.tvlib.extensions.CursorExt.isNotEmpty
 import timber.log.Timber
 import kotlin.coroutines.CoroutineContext
@@ -252,8 +249,7 @@ open class CachingCursor<T>(
     @Suppress("SpellCheckingInspection", "DEPRECATION")
     private fun _requery(): Boolean {
         cache.clear()
-        val ret = cursor?.requery() ?: false
-        return ret
+        return cursor?.requery() ?: false
     }
 
     override fun isClosed(): Boolean =

+ 0 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/ItemCard.kt

@@ -27,14 +27,11 @@ import androidx.tv.material3.CardGlow
 import androidx.tv.material3.CardScale
 import androidx.tv.material3.CardShape
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
@@ -56,14 +53,12 @@ fun ItemCard(
     border: CardBorder = CardDefaults.colorFocusBorder(Color.Green),
     glow: CardGlow = CardDefaults.colorFocusGlow(Color.Green),
     aspectRatio: Float = 16f / 9f,
-    imageLoader: ImageLoader = rememberImageLoader(),
     imageRenderer: @Composable () -> Unit = {
         ImageAny(
             modifier = modifier.fillMaxSize(),
             src = (item as? ItemWithImage<*>)?.image,
             contentDescription = (item as? ItemWithDescription<*>)?.description?.toString(),
             contentScale = contentScale,
-            imageLoader = imageLoader
         )
     },
     cardWidth: Dp = computeCardWidth(),

+ 0 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/PhotoCard.kt

@@ -24,15 +24,12 @@ import androidx.compose.ui.unit.dp
 import androidx.tv.material3.CardDefaults
 import androidx.tv.material3.CardScale
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.isFocused
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
@@ -57,7 +54,6 @@ fun PhotoCard(
     contrast: Float = 5f,
     @FloatRange(from = -255.0, to = 255.0)
     brightness: Float = -255f,
-    imageLoader: ImageLoader = rememberImageLoader(),
     imageRenderer: @Composable () -> Unit = {
         PhotoImage(
             modifier = Modifier.fillMaxSize(),
@@ -65,7 +61,6 @@ fun PhotoCard(
             contentScale = contentScale,
             contrast = contrast,
             brightness = brightness,
-            imageLoader = imageLoader,
             borderColor = if (focusState.isFocused) Color.Green else Color.Black,
             contentDescription = (item as? ItemWithDescription<*>)?.description?.toString(),
         )
@@ -81,7 +76,6 @@ fun PhotoCard(
 ) {
     ItemCard(
         item = item,
-        imageLoader = imageLoader,
         modifier = modifier.recomposeHighlighter(),
         contentScale = contentScale,
         textColor = textColor,

+ 0 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/BigCarousel.kt

@@ -23,12 +23,9 @@ import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.unit.dp
 import androidx.tv.material3.CardScale
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.detectSwipe
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.card.FocusHelper
@@ -41,7 +38,6 @@ fun BigCarousel(
     modifier: Modifier = Modifier,
     items: List<Any?> = listOf(Unit, Unit, Unit),
     autoScrollDurationMillis: Long = 8000,
-    imageLoader: ImageLoader = rememberImageLoader(),
     carouselState: CarouselState = remember(items) { CarouselState() },
     onItemSelected: ((movie: Any?) -> Unit)? = null,
     onItemClicked: ((movie: Any?) -> Unit)? = null,
@@ -89,7 +85,6 @@ fun BigCarousel(
             contentScale = ContentScale.Crop,
             scale = CardScale.None,
             focusState = cardFocusState,
-            imageLoader = imageLoader,
             onFocus = {
                 onItemSelected?.invoke(it)
             },

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/Carousel.kt

@@ -51,8 +51,8 @@ import org.mjdev.tvlib.ui.components.carousel.ModifierExt.handleKeyEvents
 @Previews
 @Composable
 fun Carousel(
-    itemCount: Int = 0,
     modifier: Modifier = Modifier,
+    itemCount: Int = 0,
     carouselState: CarouselState = remember(itemCount) { CarouselState() },
     autoScrollDurationMillis: Long = CarouselDefaults.TimeToDisplayItemMillis,
     contentTransformStartToEnd: ContentTransform = CarouselDefaults.contentTransform,

+ 0 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/CarouselCard.kt

@@ -20,12 +20,9 @@ import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.dp
 import androidx.tv.material3.CardScale
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithBackground
@@ -59,7 +56,6 @@ fun CarouselCard(
             contentScale = contentScale,
         )
     },
-    imageLoader: ImageLoader = rememberImageLoader(),
     titlePadding: PaddingValues = PaddingValues(8.dp, 12.dp, 8.dp, 12.dp),
     onFocus: (item: Any?) -> Unit = {},
     onClick: (item: Any?) -> Unit = {}
@@ -80,7 +76,6 @@ fun CarouselCard(
         imageRenderer = imageRenderer,
         titlePadding = titlePadding,
         onFocus = onFocus,
-        imageLoader = imageLoader,
         onClick = { onClick(item) }
     )
 }

+ 0 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/gallery/Gallery.kt

@@ -145,7 +145,6 @@ fun Gallery(
         }
     },
     listState: TvLazyListState = rememberTvLazyListState(),
-
     customOverlay: @Composable (item: Any?) -> Unit = {}
 ) {
     val initialized = remember { mutableStateOf(false) }

+ 0 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/gridview/TvGridView.kt

@@ -24,7 +24,6 @@ import androidx.tv.foundation.lazy.grid.items
 import androidx.tv.foundation.lazy.grid.rememberTvLazyGridState
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
 import org.mjdev.tvlib.ui.components.card.PhotoCard

+ 2 - 7
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/CircleImage.kt

@@ -24,11 +24,8 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import coil.ImageLoader
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @SuppressLint("ModifierParameter")
@@ -41,8 +38,7 @@ fun CircleImage(
     borderSize: Dp = 3.dp,
     contentDescription: String = "",
     contentPadding: Dp = 2.dp,
-    src: Any? = R.drawable.person,
-    imageLoader: ImageLoader = rememberImageLoader(),
+    src: Any? = R.drawable.person
 ) {
     Box(
         modifier = modifier
@@ -65,8 +61,7 @@ fun CircleImage(
                 ),
             src = src,
             contentDescription = contentDescription,
-            contentScale = ContentScale.Crop,
-            imageLoader = imageLoader
+            contentScale = ContentScale.Crop
         )
     }
 }

+ 1 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/FadingPhotoImage.kt

@@ -26,10 +26,8 @@ import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import coil.ImageLoader
 import kotlinx.coroutines.delay
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 
 @Previews
 @Composable
@@ -54,7 +52,6 @@ fun FadingPhotoImage(
     colorFilter: ColorFilter? = null,
     contentDescription: String? = null,
     alignment: Alignment = Alignment.Center,
-    imageLoader: ImageLoader = rememberImageLoader(),
 ) {
     val fadingImage = remember { mutableStateOf(initialImage) }
     Crossfade(
@@ -75,8 +72,7 @@ fun FadingPhotoImage(
             alpha = alpha,
             colorFilter = colorFilter,
             contentDescription = contentDescription,
-            alignment = alignment,
-            imageLoader = imageLoader
+            alignment = alignment
         )
     }
     LaunchedEffect(fadingImageState.value) {

+ 3 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageAny.kt

@@ -29,7 +29,6 @@ import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.unit.dp
-import coil.ImageLoader
 import com.skydoves.landscapist.ImageOptions
 import com.skydoves.landscapist.coil.CoilImage
 import org.mjdev.tvlib.R
@@ -50,12 +49,10 @@ fun ImageAny(
     contentScale: ContentScale = ContentScale.Fit,
     alpha: Float = DefaultAlpha,
     colorFilter: ColorFilter? = null,
-    imageLoader: ImageLoader = rememberImageLoader(),
 ) = BoxWithConstraints(
     modifier = modifier,
     contentAlignment = Alignment.Center
 ) {
-
     val width = if (constraints.minWidth == 0) 1 else constraints.minWidth
     val height = if (constraints.minHeight == 0) 1 else constraints.minHeight
 
@@ -135,7 +132,7 @@ fun ImageAny(
 
         is URL -> CoilImage(
             imageLoader = {
-                imageLoader
+                rememberImageLoader()
             },
             modifier = modifier.recomposeHighlighter(),
             imageModel = {
@@ -152,7 +149,7 @@ fun ImageAny(
 
         is Uri -> CoilImage(
             imageLoader = {
-                imageLoader
+                rememberImageLoader()
             },
             modifier = modifier.recomposeHighlighter(),
             imageModel = {
@@ -169,7 +166,7 @@ fun ImageAny(
 
         is String -> CoilImage(
             imageLoader = {
-                imageLoader
+                rememberImageLoader()
             },
             modifier = modifier.recomposeHighlighter(),
             imageModel = {

+ 2 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageBackground.kt

@@ -23,6 +23,7 @@ import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.platform.LocalContext
 import androidx.core.graphics.drawable.toBitmap
+import coil.ImageLoader
 import coil.request.CachePolicy
 import coil.request.ImageRequest
 import org.mjdev.tvlib.annotations.Previews
@@ -50,10 +51,10 @@ fun ImageBackground(
     shape: Shape = RectangleShape,
     transform: ((color: Color) -> Brush)? = null,
     contentAlignment: Alignment = Alignment.TopStart,
+    imageLoader: ImageLoader = rememberImageLoader(),
     content: @Composable (bckColor: Color) -> Unit = {}
 ) {
     val context = LocalContext.current
-    val imageLoader = rememberImageLoader()
     val bckColor = remember { mutableStateOf(Color.Transparent) }
     Box(
         modifier = modifier

+ 9 - 12
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/PhotoImage.kt

@@ -26,10 +26,8 @@ import androidx.compose.ui.graphics.DefaultAlpha
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.asAndroidBitmap
 import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import coil.ImageLoader
 import com.skydoves.landscapist.ImageOptions
 import com.skydoves.landscapist.coil.CoilImage
 import com.skydoves.landscapist.coil.CoilImageState
@@ -71,20 +69,13 @@ fun PhotoImage(
     shape: Shape = RoundedCornerShape(roundCornerSize),
     colorFilter: ColorFilter? = null,
     contentDescription: String? = null,
-    imageLoader: ImageLoader = rememberImageLoader(),
-    imageOptions: ImageOptions = ImageOptions(
-        contentScale = contentScale,
-        alignment = alignment,
-        contentDescription = contentDescription,
-        alpha = alpha,
-        colorFilter = colorFilter,
-    ),
+
     onImageStateChanged: (state: CoilImageState) -> Unit = {}
 ) {
     val isEdit = isEditMode()
     CoilImage(
         imageLoader = {
-            imageLoader
+            rememberImageLoader()
         },
         imageModel = {
             src
@@ -99,7 +90,13 @@ fun PhotoImage(
                 BorderStroke(borderSize, borderColor),
                 shape
             ),
-        imageOptions = imageOptions,
+        imageOptions = ImageOptions(
+            contentScale = contentScale,
+            alignment = alignment,
+            contentDescription = contentDescription,
+            alpha = alpha,
+            colorFilter = colorFilter,
+        ),
         failure = { failure ->
             Timber.e(failure.reason)
             placeholder()

+ 0 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/NativePlayerImpl.kt

@@ -37,7 +37,6 @@ import androidx.media3.common.Tracks
 import androidx.media3.common.VideoSize
 import androidx.media3.common.text.CueGroup
 import androidx.media3.common.util.Size
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 

+ 2 - 9
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavHostEx.kt

@@ -22,9 +22,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.ContentScale
 import androidx.navigation.NavBackStackEntry
 import androidx.navigation.compose.NavHost
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.createGraph
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
@@ -42,7 +40,6 @@ fun NavHostEx(
     route: String? = null,
     startRoute: String? = null,
     navController: NavHostControllerEx = rememberNavControllerEx(),
-    imageLoader: ImageLoader = rememberImageLoader(),
     contentAlignment: Alignment = Alignment.Center,
     enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = {
         fadeIn(animationSpec = tween(700))
@@ -64,13 +61,10 @@ fun NavHostEx(
         contrast = 4f,
         alpha = 0.7f,
         brightness = -255f,
-        contentScale = ContentScale.Crop,
-        imageLoader = imageLoader
+        contentScale = ContentScale.Crop
     )
     ScreenView(
         modifier = modifier.recomposeHighlighter(),
-        navController = navController,
-//        imageLoader = imageLoader
     ) {
         NavHost(
             modifier = modifier.recomposeHighlighter(),
@@ -87,8 +81,7 @@ fun NavHostEx(
             enterTransition = enterTransition,
             exitTransition = exitTransition,
             popEnterTransition = popEnterTransition,
-            popExitTransition = popExitTransition,
-//            imageLoader = imageLoader
+            popExitTransition = popExitTransition
         )
     }
 }

+ 2 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/Navigation.kt

@@ -35,7 +35,6 @@ fun Navigation(
     modifier: Modifier = Modifier,
     navController: NavHostControllerEx = rememberNavControllerEx(),
     content: @Composable () -> Unit = { Page() },
-//    imageLoader: ImageLoader = rememberImageLoader(),
     menuItems: List<MenuItem> = if (isEditMode()) listOf(
         MenuItem.MENU_ITEM_EXIT,
         MenuItem.MENU_ITEM_SETTINGS,
@@ -65,8 +64,7 @@ fun Navigation(
             drawerState = navController.settingsDrawerState,
             onTouchOutside = {
                 navController.closeSettings()
-            },
-//            imageLoader = imageLoader
+            }
         ) {
             if (navController.isMenuEnabled) {
                 val drawerContent: @Composable (DrawerValue) -> Unit = { state ->
@@ -96,8 +94,7 @@ fun Navigation(
                         modifier = modifier.fillMaxHeight(),
                         drawerState = navController.menuDrawerState,
                         content = mainContent,
-                        drawerContent = drawerContent,
-//                        imageLoader = imageLoader
+                        drawerContent = drawerContent
                     )
                 }
             } else {

+ 0 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/SettingsDrawer.kt

@@ -17,9 +17,7 @@ import androidx.tv.material3.DrawerState
 import androidx.tv.material3.DrawerValue
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.rememberDrawerState
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 
 @OptIn(ExperimentalTvMaterial3Api::class)
@@ -27,7 +25,6 @@ import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 @Composable
 fun SettingsDrawer(
     modifier: Modifier = Modifier,
-//    imageLoader: ImageLoader = ComposeExt.rememberImageLoader(),
     drawerState: DrawerState = rememberDrawerState(
         if (isEditMode()) DrawerValue.Open
         else DrawerValue.Closed

+ 4 - 12
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/Page.kt

@@ -17,34 +17,26 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.sp
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.requestFocusOnTouch
 import org.mjdev.tvlib.ui.components.complex.VerticalScrollableBox
-import org.mjdev.tvlib.navigation.NavHostControllerEx
 import org.mjdev.tvlib.ui.components.text.TextAny
 
 open class Page {
 
-    var navController: NavHostControllerEx? = null
-
     open val title: Any? = null
     open val icon: Any? = null
 
-    val focusRequester
-        @Composable
-        get() = rememberFocusRequester(title)
-
-    val imageLoader
-        @Composable
-        get() = rememberImageLoader()
+    private val focusRequester by lazy {
+        FocusRequester()
+    }
 
     @SuppressLint("ComposableNaming")
     @Previews

+ 0 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/PagerScope.kt

@@ -43,7 +43,6 @@ class PagerScope(
         menuGravity: MenuItem.Gravity = Center,
         isStartPage: Boolean = false
     ) {
-        page.navController = navController
         addUnique(page)
         if (isStartPage) {
             currentPage.value = size - 1

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/screen/ScreenView.kt

@@ -13,10 +13,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.navigation.NavHostControllerEx
@@ -29,7 +26,6 @@ import org.mjdev.tvlib.ui.components.page.Page
 fun ScreenView(
     modifier: Modifier = Modifier,
     navController: NavHostControllerEx = rememberNavControllerEx(),
-//    imageLoader: ImageLoader = rememberImageLoader(),
     content: @Composable () -> Unit = { Page() }
 ) {
     Box(
@@ -41,8 +37,7 @@ fun ScreenView(
         if (navController.isMenuEnabled) {
             Navigation(
                 navController = navController,
-                content = content,
-//                imageLoader = imageLoader
+                content = content
             )
         } else content()
     }

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

@@ -22,14 +22,11 @@ import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
 import org.mjdev.tvlib.helpers.apps.App
 import org.mjdev.tvlib.helpers.apps.rememberAppsManager
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.ui.components.card.ItemCard
 
 @OptIn(ExperimentalTvMaterial3Api::class)
@@ -45,7 +42,6 @@ fun AppsRow(
     startApp: Context.(app: App?) -> Unit = { app ->
         startActivity(app?.intent)
     },
-    imageLoader: ImageLoader = rememberImageLoader(),
     apps: State<List<App>> = rememberAppsManager().collectAsState(emptyList())
 ) {
     val context: Context = LocalContext.current
@@ -71,8 +67,7 @@ fun AppsRow(
                     cardWidth = cardWidth,
                     onClick = { app ->
                         startApp(context, app as? App)
-                    },
-                    imageLoader = imageLoader
+                    }
                 )
             },
         )

+ 2 - 9
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/BrowseView.kt

@@ -19,14 +19,11 @@ import androidx.compose.runtime.State
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
-import coil.ImageLoader
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithTitle
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.ui.components.carousel.BigCarousel
 
 @Previews
@@ -53,7 +50,6 @@ fun BrowseView(
     verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(32.dp),
     contentPadding: PaddingValues = PaddingValues(8.dp),
     customRows: List<@Composable () -> Unit> = emptyList(),
-    imageLoader: ImageLoader = rememberImageLoader(),
     onTitleClicked: () -> Unit = {},
     onClockClicked: () -> Unit = {},
     onMessageBadgeClicked: () -> Unit = {},
@@ -79,7 +75,6 @@ fun BrowseView(
                 onClockClick = onClockClicked,
                 onMessageBadgeClick = onMessageBadgeClicked,
                 onUserPicClick = onUserPicClicked,
-                imageLoader = imageLoader,
             )
         }
         item {
@@ -125,8 +120,7 @@ fun BrowseView(
                 modifier = Modifier.recomposeHighlighter(),
                 items = featuredItems,
                 onItemSelected = onItemFocused,
-                onItemClicked = onItemClicked,
-                imageLoader = imageLoader
+                onItemClicked = onItemClicked
             )
         }
         items(customRows) { row -> row.invoke() }
@@ -139,8 +133,7 @@ fun BrowseView(
                 onItemFocus = {
                     onItemFocused(it)
                 },
-                onItemClick = onItemClicked,
-                imageLoader = imageLoader,
+                onItemClick = onItemClicked
             )
         }
     }

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CategoryRow.kt

@@ -31,11 +31,8 @@ import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.card.PhotoCard
 import org.mjdev.tvlib.ui.components.text.TextAny
@@ -56,15 +53,13 @@ fun CategoryRow(
     backgroundShape: Shape = RoundedCornerShape(roundCornerSize),
     onItemFocus: (item: Any?) -> Unit = {},
     onItemClick: (item: Any?) -> Unit = {},
-    imageLoader: ImageLoader = rememberImageLoader(),
     contentOfItem: @Composable (item: Any?) -> Unit = { item ->
         PhotoCard(
             item = item,
             contentScale = contentScale,
             cardWidth = cardWidth,
             onClick = onItemClick,
-            onFocus = onItemFocus,
-            imageLoader = imageLoader,
+            onFocus = onItemFocus
         )
     },
 ) {

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CursorRow.kt

@@ -36,11 +36,8 @@ import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.extensions.CursorExt.getData
 import org.mjdev.tvlib.extensions.CursorExt.isNotEmpty
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
@@ -67,7 +64,6 @@ fun CursorRow(
     selection: String? = null,
     selectionArgs: Array<String>? = null,
     sortOrder: String? = null,
-    imageLoader: ImageLoader = rememberImageLoader(),
     transform: (Cursor) -> Any? = { it },
     cursor: Cursor? = rememberCursor(
         uri = uri,
@@ -122,8 +118,7 @@ fun CursorRow(
                         onFocus = onItemFocus,
                         onClick = { i ->
                             openItem(context, i)
-                        },
-                        imageLoader = imageLoader
+                        }
                     )
                 }
             }

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

@@ -30,13 +30,11 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import coil.ImageLoader
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.ui.components.badge.Badge
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 
@@ -54,7 +52,6 @@ fun Header(
     padding: Dp = 0.dp,
     contentPadding: Dp = 2.dp,
     messagesCount: Int = 0,
-    imageLoader: ImageLoader = rememberImageLoader(),
     onTitleClick: () -> Unit = {},
     onClockClick: () -> Unit = {},
     onMessageBadgeClick: () -> Unit = {},
@@ -113,8 +110,7 @@ fun Header(
                 borderColor = Color.White,
                 contentPadding = contentPadding,
                 borderSize = 1.dp,
-                onClick = onUserPicClick,
-                imageLoader = imageLoader
+                onClick = onUserPicClick
             )
         }
         Row(

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalAudioRow.kt

@@ -19,12 +19,9 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
-import coil.ImageLoader
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.helpers.cursor.AudioItem
 import org.mjdev.tvlib.helpers.cursor.CachingCursor.Companion.rememberCursor
 
@@ -43,7 +40,6 @@ fun LocalAudioRow(
     sortOrder: String? = AudioItem.SORT_ORDER_DATE_DESC,
     cardWidth: Dp = computeCardWidth(),
     contentScale: ContentScale = ContentScale.Crop,
-    imageLoader: ImageLoader = rememberImageLoader(),
     transform: (Cursor) -> Any? = { c -> AudioItem(c) },
     cursor: Cursor? = rememberCursor(
         uri = AudioItem.URI,
@@ -72,6 +68,5 @@ fun LocalAudioRow(
     transform = transform,
     onItemFocus = onItemFocus,
     openItem = openItem,
-    cursor = cursor,
-    imageLoader = imageLoader
+    cursor = cursor
 )

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalPhotosRow.kt

@@ -19,12 +19,9 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
-import coil.ImageLoader
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.helpers.cursor.CachingCursor.Companion.rememberCursor
 import org.mjdev.tvlib.helpers.cursor.PhotoItem
 
@@ -43,7 +40,6 @@ fun LocalPhotosRow(
     sortOrder: String? = PhotoItem.SORT_ORDER_DATE_DESC,
     cardWidth: Dp = computeCardWidth(),
     contentScale: ContentScale = ContentScale.Crop,
-    imageLoader: ImageLoader = rememberImageLoader(),
     transform: (Cursor) -> Any? = { c -> PhotoItem(c) },
     cursor: Cursor? = rememberCursor(
         uri = PhotoItem.URI,
@@ -72,6 +68,5 @@ fun LocalPhotosRow(
     transform = transform,
     openItem = openItem,
     onItemFocus = onItemFocus,
-    cursor = cursor,
-    imageLoader = imageLoader
+    cursor = cursor
 )

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/LocalVideoRow.kt

@@ -19,12 +19,9 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
-import coil.ImageLoader
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.helpers.cursor.CachingCursor.Companion.rememberCursor
 import org.mjdev.tvlib.helpers.cursor.VideoItem
 
@@ -43,7 +40,6 @@ fun LocalVideoRow(
     sortOrder: String? = VideoItem.SORT_ORDER_DATE_DESC,
     cardWidth: Dp = computeCardWidth(),
     contentScale: ContentScale = ContentScale.Crop,
-    imageLoader: ImageLoader = rememberImageLoader(),
     transform: (Cursor) -> Any? = { c -> VideoItem(c) },
     cursor: Cursor? = rememberCursor(
         uri = VideoItem.URI,
@@ -73,7 +69,6 @@ fun LocalVideoRow(
         transform = { c -> VideoItem(c) },
         openItem = openItem,
         onItemFocus = onItemFocus,
-        cursor = cursor,
-        imageLoader = imageLoader
+        cursor = cursor
     )
 }

+ 0 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Tabs.kt

@@ -29,9 +29,7 @@ import androidx.tv.material3.Tab
 import androidx.tv.material3.TabDefaults
 import androidx.tv.material3.TabRow
 import androidx.tv.material3.TabRowDefaults
-import coil.ImageLoader
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
 import org.mjdev.tvlib.extensions.ComposeExt.isFocused
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvlib.extensions.ComposeExt.rememberMutableInteractionSource
@@ -52,7 +50,6 @@ fun Tabs(
     activeContentColor: Color = Color.Green,
     selectedContentColor: Color = Color.White,
     focusedContentColor: Color = Color.White,
-//    imageLoader: ImageLoader = rememberImageLoader(),
     interactionSource: MutableInteractionSource = rememberMutableInteractionSource(items),
     onItemClick: (item: Any?) -> Unit = {}
 ) {

+ 1 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/UserPic.kt

@@ -19,14 +19,11 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
-import coil.ImageLoader
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
 import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ComposeExt
-import org.mjdev.tvlib.extensions.ComposeExt.rememberImageLoader
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 import org.mjdev.tvlib.ui.components.image.CircleImage
 
@@ -41,7 +38,6 @@ fun UserPic(
     borderColor: Color = Color.White,
     borderSize: Dp = 2.dp,
     contentPadding: Dp = 2.dp,
-    imageLoader: ImageLoader = rememberImageLoader(),
     onClick: () -> Unit = {}
 ) = FocusableBox(
     modifier = modifier.wrapContentSize(),
@@ -58,7 +54,6 @@ fun UserPic(
         borderSize = borderSize,
         borderColor = borderColor,
         contentPadding = contentPadding + borderSize,
-        src = src,
-        imageLoader = imageLoader
+        src = src
     )
 }

+ 27 - 31
tvlib/src/main/kotlin/org/mjdev/tvlib/updater/AppUpdater.kt

@@ -8,11 +8,7 @@
 
 package org.mjdev.tvlib.updater
 
-import android.content.ActivityNotFoundException
 import android.content.Context
-import android.content.Intent
-import android.net.Uri
-import androidx.annotation.AnyThread
 import androidx.annotation.MainThread
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.remember
@@ -103,34 +99,34 @@ class AppUpdater(
 //        }
     }
 
-    @AnyThread
-    private fun downloadFile(
-        url: String,
-        finalizeBlock: () -> Unit
-    ) {
-        // todo simply open download yet, until finished
-        try {
-            context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
-                flags = Intent.FLAG_ACTIVITY_NEW_TASK
-            })
-            finalizeBlock()
-        } catch (e: ActivityNotFoundException) {
-            Timber.e(e)
-        }
-        // todo
-//        httpClient.download(url) { result ->
-//            result.onSuccess { data ->
-//                FileOutputStream(externalFile).apply {
-//                    write(data)
-//                    flush()
-//                    close()
-//                    finalizeBlock()
-//                }
-//            }.onFailure { e ->
-//                Timber.e(e)
-//            }
+//    @AnyThread
+//    private fun downloadFile(
+//        url: String,
+//        finalizeBlock: () -> Unit
+//    ) {
+//        // todo simply open download yet, until finished
+//        try {
+//            context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)).apply {
+//                flags = Intent.FLAG_ACTIVITY_NEW_TASK
+//            })
+//            finalizeBlock()
+//        } catch (e: ActivityNotFoundException) {
+//            Timber.e(e)
 //        }
-    }
+//        // todo
+////        httpClient.download(url) { result ->
+////            result.onSuccess { data ->
+////                FileOutputStream(externalFile).apply {
+////                    write(data)
+////                    flush()
+////                    close()
+////                    finalizeBlock()
+////                }
+////            }.onFailure { e ->
+////                Timber.e(e)
+////            }
+////        }
+//    }
 
 //    @AnyThread
 //    private suspend fun startUpdate() {

+ 8 - 7
tvlib/src/main/kotlin/org/mjdev/tvlib/webclient/CustomWebViewClient.kt

@@ -35,13 +35,13 @@ open class CustomWebViewClient(
 //            Timber.d("Blocked url: ${request?.url}")
 //            return null
 //        } else {
-            uri?.let {
-                if (!loadedResources.contains(it)) {
-                    loadedResources.add(it)
-                }
+        uri?.let {
+            if (!loadedResources.contains(it)) {
+                loadedResources.add(it)
             }
-            Timber.d("Loading url: $uri")
-            return WebViewCacheInterceptorInst.instance?.interceptRequest(request)
+        }
+        Timber.d("Loading url: $uri")
+        return WebViewCacheInterceptorInst.instance?.interceptRequest(request)
 //        }
     }
 
@@ -127,7 +127,8 @@ open class CustomWebViewClient(
         Timber.e("$errorCode : $description")
     }
 
-    @Deprecated("Deprecated in Java",
+    @Deprecated(
+        "Deprecated in Java",
         ReplaceWith("Timber.e(\"Too many redirects.\")", "timber.log.Timber")
     )
     override fun onTooManyRedirects(

+ 6 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/webclient/html/HtmlElement.kt

@@ -3,6 +3,7 @@ package org.mjdev.tvlib.webclient.html
 import org.mjdev.tvlib.webclient.javascript.JSI
 import org.jsoup.nodes.Element
 
+@Suppress("unused", "MemberVisibilityCanBePrivate", "SpellCheckingInspection")
 abstract class HtmlElement(var element: Element, val jsi: JSI) {
     abstract val tag: String
 
@@ -13,7 +14,7 @@ abstract class HtmlElement(var element: Element, val jsi: JSI) {
     val childs: List<HtmlElement>
         get() = element.children().map { e -> parseElement(e, jsi) }
     val firstChild: HtmlElement
-        get() = element.child(0).let { e -> parseElement(e, jsi) }
+        get() = parseElement(element.child(0), jsi)
 
     fun childrenSize(): Int = element.childrenSize()
 
@@ -23,7 +24,7 @@ abstract class HtmlElement(var element: Element, val jsi: JSI) {
         }
     }
 
-    fun ownText(): String = element.ownText() ?: ""
+    fun ownText(): String = element.ownText()
 
     inline fun <reified T> newInstance(jsi: JSI): T = T::class
         .java
@@ -36,9 +37,9 @@ abstract class HtmlElement(var element: Element, val jsi: JSI) {
 
     inline fun <reified T : HtmlElement> getAllElements(): List<T> {
         val instance: T = newInstance(jsi)
-        return element.getElementsByTag(instance.tag).map {
+        return element.getElementsByTag(instance.tag).mapNotNull {
             parseElement(it, jsi) as T?
-        }.filterNotNull()
+        }
     }
 
     inline fun <reified T : HtmlElement> getElement(): T {
@@ -48,8 +49,7 @@ abstract class HtmlElement(var element: Element, val jsi: JSI) {
         } ?: newInstance(jsi)
     }
 
-    fun attr(attrName: String, defaultValue: String = ""): String =
-        element.attr(attrName) ?: defaultValue
+    fun attr(attrName: String): String =  element.attr(attrName)
 
     fun attr(attrName: String, value: Any?) {
         element.attr(attrName, value.toString())