Explorar el Código

navigation improvements / need more improvements

Milan Jurkulak hace 2 años
padre
commit
500fc7a9ef
Se han modificado 54 ficheros con 285 adiciones y 493 borrados
  1. 2 31
      app/build.gradle.kts
  2. 0 1
      app/src/main/kotlin/org/mjdev/tvapp/activity/MainActivity.kt
  3. 2 0
      app/src/main/res/values/strings.xml
  4. 0 1
      gradle.properties
  5. 0 8
      tvlib/build.gradle.kts
  6. 65 79
      tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ModifierExt.kt
  7. 4 0
      tvlib/src/main/kotlin/org/mjdev/tvlib/navigation/NavHostControllerEx.kt
  8. 2 4
      tvlib/src/main/kotlin/org/mjdev/tvlib/screen/ScreenWithPages.kt
  9. 1 4
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/badge/Badge.kt
  10. 1 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/button/Button.kt
  11. 0 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/Card.kt
  12. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/CardContent.kt
  13. 2 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/ItemCard.kt
  14. 3 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/PhotoCard.kt
  15. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/PreviewCard.kt
  16. 1 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/BigCarousel.kt
  17. 1 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/carousel/CarouselCard.kt
  18. 0 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/FocusableBox.kt
  19. 2 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/FocusableCard.kt
  20. 3 4
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/VerticalScrollableBox.kt
  21. 10 11
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/icon/IconAny.kt
  22. 0 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/CircleImage.kt
  23. 15 13
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/FadingPhotoImage.kt
  24. 8 9
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageAny.kt
  25. 6 9
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/PhotoImage.kt
  26. 2 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/ExoPlayerImpl.kt
  27. 0 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/MediaPlayerContainer.kt
  28. 2 7
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/NativePlayerImpl.kt
  29. 12 92
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavDrawerContent.kt
  30. 2 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavHostEx.kt
  31. 5 11
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/Navigation.kt
  32. 50 33
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavigationRow.kt
  33. 0 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/SettingsDrawerContent.kt
  34. 5 12
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/Page.kt
  35. 3 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/PagerScope.kt
  36. 2 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/TvPager.kt
  37. 1 4
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/screen/ScreenView.kt
  38. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/AutoHideEmptyText.kt
  39. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/CircleText.kt
  40. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/TextAny.kt
  41. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/TextWithShadow.kt
  42. 3 3
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/AppUpdateAvailableMessage.kt
  43. 2 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/BrowseView.kt
  44. 1 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CategoryRow.kt
  45. 5 6
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Clock.kt
  46. 1 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/CursorRow.kt
  47. 24 17
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/ErrorMessage.kt
  48. 4 17
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Header.kt
  49. 3 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/NetworkErrorMessage.kt
  50. 4 8
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/ScrollableTvLazyColumn.kt
  51. 1 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/TVRow.kt
  52. 13 18
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Tabs.kt
  53. 3 7
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Title.kt
  54. 3 5
      tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/UserPic.kt

+ 2 - 31
app/build.gradle.kts

@@ -102,7 +102,7 @@ android {
             resValue(
                 "string",
                 "app_name",
-                "TV ${applicationIdSuffix.toString().replace(".","").capitalize()}"
+                "TV App  ${applicationIdSuffix.toString().replace(".", "").capitalize()}"
             )
         }
 
@@ -130,38 +130,9 @@ android {
             resValue(
                 "string",
                 "app_name",
-                "TV ${applicationIdSuffix.toString().replace(".","").capitalize()}"
+                "TV App  ${applicationIdSuffix.toString().replace(".", "").capitalize()}"
             )
         }
-
-        create("recomposing") {
-            applicationIdSuffix = ".rcmps"
-            isDebuggable = true
-            isMinifyEnabled = false
-            isShrinkResources = false
-            isCrunchPngs = false
-            isEmbedMicroApp = true
-            proguardFiles(
-                getDefaultProguardFile("proguard-android-optimize.txt"),
-                "proguard-rules.pro"
-            )
-            buildConfigField(
-                "String",
-                "SYNC_AUTH",
-                "\"${defaultConfig.applicationId}$applicationIdSuffix.sync\""
-            )
-            resValue(
-                "string",
-                "sync_auth",
-                "${defaultConfig.applicationId}$applicationIdSuffix.sync"
-            )
-            resValue(
-                "string",
-                "app_name",
-                "TV ${applicationIdSuffix.toString().replace(".","").capitalize()}"
-            )
-            matchingFallbacks += listOf("debug")
-        }
     }
 
     buildFeatures {

+ 0 - 1
app/src/main/kotlin/org/mjdev/tvapp/activity/MainActivity.kt

@@ -10,7 +10,6 @@ package org.mjdev.tvapp.activity
 
 import androidx.compose.runtime.Composable
 import dagger.hilt.android.AndroidEntryPoint
-import org.mjdev.tvlib.extensions.NavGraphBuilderExt.screen
 import org.mjdev.tvlib.navigation.NavGraphBuilderEx
 import org.mjdev.tvapp.ui.screens.MainScreen
 import org.mjdev.tvapp.ui.screens.SplashScreen

+ 2 - 0
app/src/main/res/values/strings.xml

@@ -9,6 +9,8 @@
 -->
 <resources>
 
+<!--    <string name="app_name" translatable="false">TVApp</string>-->
+
     <string name="bt_dismiss">Dismiss</string>
     <string name="bt_update">Update</string>
 

+ 0 - 1
gradle.properties

@@ -21,7 +21,6 @@ kotlin.code.style=official
 # resources declared in the library itself and none from the library's dependencies,
 # thereby reducing the size of the R class for that library
 android.nonTransitiveRClass=true
-android.defaults.buildfeatures.buildconfig=true
 org.gradle.unsafe.configuration-cache=false
 android.suppressUnsupportedCompileSdk=34
 android.nonFinalResIds=true

+ 0 - 8
tvlib/build.gradle.kts

@@ -49,14 +49,6 @@ android {
             )
             buildConfigField("Boolean", "RECOMPOSE_ENABLED", "false")
         }
-        create("recomposing") {
-            isMinifyEnabled = false
-            proguardFiles(
-                getDefaultProguardFile("proguard-android-optimize.txt"),
-                "proguard-rules.pro"
-            )
-            buildConfigField("Boolean", "RECOMPOSE_ENABLED", "true")
-        }
     }
 
     compileOptions {

+ 65 - 79
tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ModifierExt.kt

@@ -10,7 +10,6 @@
 
 package org.mjdev.tvlib.extensions
 
-import android.annotation.SuppressLint
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.gestures.detectDragGestures
 import androidx.compose.foundation.gestures.detectTapGestures
@@ -18,40 +17,27 @@ import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.relocation.BringIntoViewResponder
 import androidx.compose.foundation.relocation.bringIntoViewResponder
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.MutableIntState
 import androidx.compose.runtime.MutableState
-import androidx.compose.runtime.Stable
 import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.mutableLongStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.composed
-import androidx.compose.ui.draw.drawWithCache
 import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.focus.focusRequester
 import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.Rect
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.graphics.drawscope.Fill
-import androidx.compose.ui.graphics.drawscope.Stroke
-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.debugInspectorInfo
-import androidx.compose.ui.unit.dp
-import kotlinx.coroutines.delay
 import org.mjdev.tvlib.BuildConfig
 import org.mjdev.tvlib.extensions.ComposeExt.isLandscapeMode
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
 import timber.log.Timber
-import java.lang.Float.min
 import kotlin.math.abs
 
 @Suppress("MemberVisibilityCanBePrivate")
@@ -147,72 +133,72 @@ object ModifierExt {
         @Composable
         get() = BuildConfig.RECOMPOSE_ENABLED
 
-    @Composable
-    @Stable
-    fun Modifier.recomposeHighlighter(
-        isComposeDebug: Boolean = isRecomposeHighlighterEnabled
-    ): Modifier = conditional(
-        isComposeDebug
-    ) {
-        this.then(recomposeModifier)
-    }
-
-    @SuppressLint("AutoboxingStateValueProperty")
-    private val recomposeModifier = Modifier.composed(
-        inspectorInfo = debugInspectorInfo {
-            name = "recomposeHighlighter"
-        }) {
-        val totalCompositions = remember { arrayOf(0L) }
-        totalCompositions[0]++
-        val totalCompositionsAtLastTimeout = remember { mutableLongStateOf(0L) }
-        LaunchedEffect(totalCompositions[0]) {
-            delay(3000)
-            totalCompositionsAtLastTimeout.value = totalCompositions[0]
-        }
-        Modifier.drawWithCache {
-            onDrawWithContent {
-                drawContent()
-                val numCompositionsSinceTimeout =
-                    totalCompositions[0] - totalCompositionsAtLastTimeout.value
-                val hasValidBorderParams = size.minDimension > 0f
-                if (!hasValidBorderParams || numCompositionsSinceTimeout <= 0) {
-                    return@onDrawWithContent
-                }
-                val (color, strokeWidthPx) =
-                    when (numCompositionsSinceTimeout) {
-                        1L -> Color.Blue to 1f
-                        2L -> Color.Green to 2.dp.toPx()
-                        else -> {
-                            lerp(
-                                Color.Yellow.copy(alpha = 0.8f),
-                                Color.Red.copy(alpha = 0.5f),
-                                min(
-                                    1f,
-                                    (numCompositionsSinceTimeout - 1).toFloat() / 100f
-                                )
-                            ) to numCompositionsSinceTimeout.toInt().dp.toPx()
-                        }
-                    }
+//    @Composable
+//    @Stable
+//    fun Modifier.recomposeHighlighter(
+//        isComposeDebug: Boolean = isRecomposeHighlighterEnabled
+//    ): Modifier = conditional(
+//        isComposeDebug
+//    ) {
+//        this.then(recomposeModifier)
+//    }
 
-                val halfStroke = strokeWidthPx / 2
-                val topLeft = Offset(halfStroke, halfStroke)
-                val borderSize = Size(
-                    size.width - strokeWidthPx,
-                    size.height - strokeWidthPx
-                )
-                val fillArea = (strokeWidthPx * 2) > size.minDimension
-                val rectTopLeft = if (fillArea) Offset.Zero else topLeft
-                val size = if (fillArea) size else borderSize
-                val style = if (fillArea) Fill else Stroke(strokeWidthPx)
-                drawRect(
-                    brush = SolidColor(color),
-                    topLeft = rectTopLeft,
-                    size = size,
-                    style = style
-                )
-            }
-        }
-    }
+//    @SuppressLint("AutoboxingStateValueProperty")
+//    private val recomposeModifier = Modifier.composed(
+//        inspectorInfo = debugInspectorInfo {
+//            name = "recomposeHighlighter"
+//        }) {
+//        val totalCompositions = remember { arrayOf(0L) }
+//        totalCompositions[0]++
+//        val totalCompositionsAtLastTimeout = remember { mutableLongStateOf(0L) }
+//        LaunchedEffect(totalCompositions[0]) {
+//            delay(3000)
+//            totalCompositionsAtLastTimeout.value = totalCompositions[0]
+//        }
+//        Modifier.drawWithCache {
+//            onDrawWithContent {
+//                drawContent()
+//                val numCompositionsSinceTimeout =
+//                    totalCompositions[0] - totalCompositionsAtLastTimeout.value
+//                val hasValidBorderParams = size.minDimension > 0f
+//                if (!hasValidBorderParams || numCompositionsSinceTimeout <= 0) {
+//                    return@onDrawWithContent
+//                }
+//                val (color, strokeWidthPx) =
+//                    when (numCompositionsSinceTimeout) {
+//                        1L -> Color.Blue to 1f
+//                        2L -> Color.Green to 2.dp.toPx()
+//                        else -> {
+//                            lerp(
+//                                Color.Yellow.copy(alpha = 0.8f),
+//                                Color.Red.copy(alpha = 0.5f),
+//                                min(
+//                                    1f,
+//                                    (numCompositionsSinceTimeout - 1).toFloat() / 100f
+//                                )
+//                            ) to numCompositionsSinceTimeout.toInt().dp.toPx()
+//                        }
+//                    }
+//
+//                val halfStroke = strokeWidthPx / 2
+//                val topLeft = Offset(halfStroke, halfStroke)
+//                val borderSize = Size(
+//                    size.width - strokeWidthPx,
+//                    size.height - strokeWidthPx
+//                )
+//                val fillArea = (strokeWidthPx * 2) > size.minDimension
+//                val rectTopLeft = if (fillArea) Offset.Zero else topLeft
+//                val size = if (fillArea) size else borderSize
+//                val style = if (fillArea) Fill else Stroke(strokeWidthPx)
+//                drawRect(
+//                    brush = SolidColor(color),
+//                    topLeft = rectTopLeft,
+//                    size = size,
+//                    style = style
+//                )
+//            }
+//        }
+//    }
 
     // todo anr
     @OptIn(ExperimentalFoundationApi::class)

+ 4 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/navigation/NavHostControllerEx.kt

@@ -13,7 +13,9 @@ import android.app.Activity
 import android.content.Context
 import android.content.Intent
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableIntState
 import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.snapshots.SnapshotStateList
@@ -53,6 +55,8 @@ class NavHostControllerEx(
 
     val backgroundState: MutableState<Any?> = mutableStateOf(null)
 
+    val selectedMenuItem: MutableIntState = mutableIntStateOf(-1)
+
     init {
         lifecycle.addObserver(this)
     }

+ 2 - 4
tvlib/src/main/kotlin/org/mjdev/tvlib/screen/ScreenWithPages.kt

@@ -19,9 +19,7 @@ open class ScreenWithPages : Screen() {
 
     open val startPageIndex: Int = 0
 
-    open val pages: PagerScope.() -> Unit = {
-        page(EMPTY_PAGE)
-    }
+    open val pages: PagerScope.() -> Unit = { page(EMPTY_PAGE) }
 
     @Previews
     @Composable
@@ -29,7 +27,7 @@ open class ScreenWithPages : Screen() {
     override fun Content() {
         TvPager(
             startIndex = startPageIndex,
-            pages = pages,
+            pages = pages
         )
     }
 

+ 1 - 4
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/badge/Badge.kt

@@ -19,7 +19,6 @@ 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 org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 import org.mjdev.tvlib.ui.components.text.CircleText
 
@@ -38,9 +37,7 @@ fun Badge(
     onClick: () -> Unit = {}
 ) {
     FocusableBox(
-        modifier = modifier
-            .clip(CircleShape)
-            .recomposeHighlighter(),
+        modifier = modifier.clip(CircleShape),
         shape = shape,
         onClick = onClick
     ) {

+ 1 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/button/Button.kt

@@ -35,7 +35,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.Glow
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.text.TextAny
 
 
@@ -71,8 +70,7 @@ fun Button(
 ) = Button(
     modifier = modifier
         .border(BorderStroke(borderSize, borderColor), shape)
-        .clickable { onClick() }
-        .recomposeHighlighter(),
+        .clickable { onClick() },
     glow = glow,
     scale = scale,
     onClick = onClick,

+ 0 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/Card.kt

@@ -39,7 +39,6 @@ import androidx.tv.material3.Glow
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.rememberMutableInteractionSource
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.tvAspectRatio
 
 @SuppressLint("ModifierParameter")
@@ -67,7 +66,6 @@ fun Card(
     androidx.tv.material3.Card(
         onClick = onClick,
         modifier = modifier
-            .recomposeHighlighter()
             .widthIn(max = 320.dp)
             .conditional(aspectRatio != null) {
                 tvAspectRatio(aspectRatio)

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/CardContent.kt

@@ -17,7 +17,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
 import androidx.tv.material3.ProvideTextStyle
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.text.AutoHideEmptyText
 
 @OptIn(ExperimentalTvMaterial3Api::class)
@@ -46,7 +45,7 @@ fun CardContent(
     },
 ) {
     Column(
-        modifier = modifier.recomposeHighlighter()
+        modifier = modifier
     ) {
         ProvideTextStyle(MaterialTheme.typography.titleMedium) {
             title.invoke()

+ 2 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/ItemCard.kt

@@ -35,7 +35,6 @@ 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.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
 import org.mjdev.tvlib.ui.components.complex.FocusableCard
@@ -60,7 +59,7 @@ fun ItemCard(
         Image(
             painter = painterResource(R.drawable.broken_image),
             "",
-            modifier.recomposeHighlighter()
+            modifier
         )
     },
     imageRenderer: @Composable () -> Unit = {
@@ -84,7 +83,7 @@ fun ItemCard(
     onFocus: (item: Any?) -> Unit = {},
     onClick: (item: Any?) -> Unit = {},
 ) = FocusableCard(
-    modifier = modifier.recomposeHighlighter(),
+    modifier = modifier,
     item = item,
     focusState = focusState,
     focusRequester = focusRequester,

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

@@ -32,7 +32,6 @@ 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.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
 import org.mjdev.tvlib.ui.components.image.ImageAny
@@ -60,7 +59,8 @@ fun PhotoCard(
     placeholder: @Composable () -> Unit = {
         ImageAny(
             modifier = Modifier.fillMaxSize().padding(64.dp),
-            src = R.drawable.broken_image
+            src = R.drawable.broken_image,
+            contentScale = contentScale
         )
     },
     imageRenderer: @Composable () -> Unit = {
@@ -85,7 +85,7 @@ fun PhotoCard(
 ) {
     ItemCard(
         item = item,
-        modifier = modifier.recomposeHighlighter(),
+        modifier = modifier,
         contentScale = contentScale,
         textColor = textColor,
         focusState = focusState,

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/card/PreviewCard.kt

@@ -50,7 +50,6 @@
 //import kotlinx.coroutines.Dispatchers
 //import kotlinx.coroutines.withContext
 //import org.mjdev.tvlib.annotations.Previews
-//import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 //import org.mjdev.tvlib.extensions.ModifierExt.tvAspectRatio
 //
 //// todo
@@ -70,7 +69,7 @@
 //    thumbnailUrl: String? = null
 //) {
 //    Card(
-//        modifier = modifier.tvAspectRatio(aspectRatio).recomposeHighlighter()
+//        modifier = modifier.tvAspectRatio(aspectRatio)
 //    ) {
 //        val context = LocalContext.current
 //        var currentlyPlaying by remember(videoUrl) { mutableStateOf(false) }

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

@@ -26,7 +26,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.swipeGestures
 import org.mjdev.tvlib.ui.components.card.FocusHelper
 
@@ -74,8 +73,7 @@ fun BigCarousel(
                 },
                 onSwipeDown = onSwipeDown,
                 onSwipeUp = onSwipeUp
-            )
-            .recomposeHighlighter(),
+            ),
     ) { indexOfCarouselItem ->
         val selectedItem = items[indexOfCarouselItem]
         onItemSelected?.invoke(selectedItem)

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

@@ -27,7 +27,6 @@ import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithBackground
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
@@ -76,8 +75,7 @@ fun CarouselCard(
         modifier = modifier
             .conditional(isEdit) {
                 defaultMinSize(260.dp)
-            }
-            .recomposeHighlighter(),
+            },
         aspectRatio = 1f,
         focused = focused,
         focusState = focusState,

+ 0 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/FocusableBox.kt

@@ -30,7 +30,6 @@ 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.ModifierExt.focusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.requestFocusOnTouch
 
 @OptIn(ExperimentalTvMaterial3Api::class)
@@ -57,7 +56,6 @@ fun FocusableBox(
     Surface(
         onClick = onClick,
         modifier = modifier
-            .recomposeHighlighter()
             .focusState(focusState)
             .onFocusChanged { state -> onFocusChange(state) }
             .requestFocusOnTouch(

+ 2 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/FocusableCard.kt

@@ -48,7 +48,6 @@ import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
 import org.mjdev.tvlib.extensions.ModifierExt.focusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.requestFocusOnTouch
 import org.mjdev.tvlib.interfaces.ItemWithDescription
 import org.mjdev.tvlib.interfaces.ItemWithImage
@@ -81,7 +80,8 @@ fun FocusableCard(
     placeholder: @Composable () -> Unit = {
         Image(
             painter = painterResource(R.drawable.broken_image),
-            contentDescription = ""
+            contentDescription = "",
+            contentScale = contentScale
         )
     },
     imageRenderer: @Composable () -> Unit = {
@@ -117,7 +117,6 @@ fun FocusableCard(
     border = border,
     glow = glow,
     modifier = modifier
-        .recomposeHighlighter()
         .size(
             width = cardWidth,
             height = cardWidth / aspectRatio

+ 3 - 4
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/VerticalScrollableBox.kt

@@ -20,9 +20,9 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.tv.foundation.lazy.list.TvLazyListState
+import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.isLandscapeMode
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @SuppressLint("AutoboxingStateValueProperty")
 @Previews
@@ -31,7 +31,7 @@ fun VerticalScrollableBox(
     modifier: Modifier = Modifier,
     contentAlignment: Alignment = Alignment.TopStart,
     propagateMinConstraints: Boolean = isLandscapeMode(),
-    state: TvLazyListState? = null,
+    state: TvLazyListState? = rememberTvLazyListState(),
     content: @Composable BoxScope.() -> Unit = {}
 ) {
     val scrollDelta = remember { mutableFloatStateOf(0f) }
@@ -41,8 +41,7 @@ fun VerticalScrollableBox(
                 detectVerticalDragGestures { _, dragAmount ->
                     scrollDelta.value = dragAmount
                 }
-            }
-            .recomposeHighlighter(),
+            },
         contentAlignment = contentAlignment,
         propagateMinConstraints = propagateMinConstraints,
     ) {

+ 10 - 11
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/icon/IconAny.kt

@@ -32,7 +32,6 @@ import com.skydoves.landscapist.ImageOptions
 import com.skydoves.landscapist.glide.GlideImage
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.DrawableExt.asImageBitmap
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import java.net.URL
 
 @OptIn(ExperimentalTvMaterial3Api::class)
@@ -56,48 +55,48 @@ fun IconAny(
         null -> Icon(
             ColorDrawable(0).asImageBitmap(width, height),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is Bitmap -> Icon(
             src.asImageBitmap(),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is ImageBitmap -> Icon(
             src,
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is Drawable -> Icon(
             src.asImageBitmap(width, height),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is Int -> Icon(
             painterResource(src),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is Color -> Icon(
             ColorDrawable(0).asImageBitmap(width, height),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 
         is URL -> GlideImage(
             imageModel = { src },
-            modifier = modifier.recomposeHighlighter(),
+            modifier = modifier,
             imageOptions = ImageOptions(
                 colorFilter = ColorFilter.tint(tint)
             )
@@ -105,7 +104,7 @@ fun IconAny(
 
         is Uri -> GlideImage(
             imageModel = { src },
-            modifier = modifier.recomposeHighlighter(),
+            modifier = modifier,
             imageOptions = ImageOptions(
                 colorFilter = ColorFilter.tint(tint)
             )
@@ -113,7 +112,7 @@ fun IconAny(
 
         is String -> GlideImage(
             imageModel = { src },
-            modifier = modifier.recomposeHighlighter(),
+            modifier = modifier,
             imageOptions = ImageOptions(
                 colorFilter = ColorFilter.tint(tint)
             )
@@ -122,7 +121,7 @@ fun IconAny(
         is ImageVector -> Icon(
             src,
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             tint
         )
 

+ 0 - 3
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/CircleImage.kt

@@ -26,7 +26,6 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @SuppressLint("ModifierParameter")
 @Previews
@@ -43,13 +42,11 @@ fun CircleImage(
     Box(
         modifier = modifier
             .padding(contentPadding)
-            .recomposeHighlighter()
             .aspectRatio(1f),
         contentAlignment = Alignment.Center,
     ) {
         ImageAny(
             modifier = modifier
-                .recomposeHighlighter()
                 .clip(CircleShape)
                 .background(backGroundColor, CircleShape)
                 .border(

+ 15 - 13
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/FadingPhotoImage.kt

@@ -11,6 +11,7 @@ package org.mjdev.tvlib.ui.components.image
 import androidx.annotation.FloatRange
 import androidx.compose.animation.Crossfade
 import androidx.compose.animation.core.tween
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
@@ -34,11 +35,10 @@ import org.mjdev.tvlib.annotations.Previews
 fun FadingPhotoImage(
     modifier: Modifier = Modifier,
     initialImage: Any? = null,
-    fadingImageState: MutableState<Any?> = remember { mutableStateOf(initialImage) },
     animationDuration: Int = 1800,
     delay: Long = 600,
     alpha: Float = 0.6f,
-    blurRadius: Dp = 4.dp,
+    blurRadius: Dp = 24.dp,
     @FloatRange(from = 0.0, to = 10.0)
     contrast: Float = 4f,
     @FloatRange(from = -255.0, to = 255.0)
@@ -52,15 +52,17 @@ fun FadingPhotoImage(
     colorFilter: ColorFilter? = null,
     contentDescription: String? = null,
     alignment: Alignment = Alignment.Center,
-) {
-    val fadingImage = remember { mutableStateOf(initialImage) }
-    Crossfade(
-        fadingImage.value,
-        animationSpec = tween(animationDuration),
-        label = "FadingImage"
-    ) { targetState ->
+    fadingImageState: MutableState<Any?> = remember { mutableStateOf(initialImage) }
+) = Crossfade(
+    modifier = modifier,
+    targetState = fadingImageState.value,
+    animationSpec = tween(animationDuration),
+    label = "FadingImage"
+) { targetState ->
+    Box(
+        modifier = Modifier.blur(radius = blurRadius)
+    ) {
         PhotoImage(
-            modifier = modifier.blur(radius = blurRadius),
             src = targetState,
             contrast = contrast,
             brightness = brightness,
@@ -76,9 +78,9 @@ fun FadingPhotoImage(
         )
     }
     LaunchedEffect(fadingImageState.value) {
-        if (fadingImage.value != fadingImageState.value) {
+        if (fadingImageState.value != fadingImageState.value) {
             delay(delay)
-            fadingImage.value = fadingImageState.value
+            fadingImageState.value = fadingImageState.value
         }
     }
-}
+}

+ 8 - 9
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/image/ImageAny.kt

@@ -33,7 +33,6 @@ import com.skydoves.landscapist.glide.GlideImage
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.DrawableExt.asImageBitmap
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import java.net.URL
 
 @Suppress("MoveVariableDeclarationIntoWhen")
@@ -52,7 +51,7 @@ fun ImageAny(
         Image(
             painterResource(R.drawable.broken_image),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -77,7 +76,7 @@ fun ImageAny(
         Color -> Image(
             ColorDrawable((imageSrc as Color).toArgb()).asImageBitmap(width, height),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -87,7 +86,7 @@ fun ImageAny(
         is Bitmap -> Image(
             imageSrc.asImageBitmap(),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -97,7 +96,7 @@ fun ImageAny(
         is ImageBitmap -> Image(
             imageSrc,
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -107,7 +106,7 @@ fun ImageAny(
         is ColorDrawable -> Image(
             imageSrc.asImageBitmap(1, 1),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -117,7 +116,7 @@ fun ImageAny(
         is Drawable -> Image(
             imageSrc.asImageBitmap(),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -127,7 +126,7 @@ fun ImageAny(
         is Int -> Image(
             painterResource(imageSrc),
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,
@@ -170,7 +169,7 @@ fun ImageAny(
         is ImageVector -> Image(
             imageSrc,
             contentDescription,
-            modifier.recomposeHighlighter(),
+            modifier,
             alignment,
             contentScale,
             alpha,

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

@@ -39,7 +39,6 @@ import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.toDrawable
 import org.mjdev.tvlib.extensions.DrawableExt.asPhoto
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import timber.log.Timber
 
 @SuppressLint("ModifierParameter")
@@ -48,14 +47,15 @@ import timber.log.Timber
 fun PhotoImage(
     src: Any? = null,
     modifier: Modifier = Modifier,
+    alignment: Alignment = Alignment.Center,
+    contentScale: ContentScale = ContentScale.Crop,
     placeholder: @Composable () -> Unit = {
         ImageAny(
             modifier = modifier,
-            src = R.drawable.broken_image
+            src = R.drawable.broken_image,
+            contentScale = contentScale
         )
     },
-    alignment: Alignment = Alignment.Center,
-    contentScale: ContentScale = ContentScale.Crop,
     alpha: Float = DefaultAlpha,
     @FloatRange(from = 0.0, to = 10.0)
     contrast: Float = 5f,
@@ -78,7 +78,6 @@ fun PhotoImage(
             imageModel = {                src            },
             modifier = modifier
                 .defaultMinSize(80.dp)
-                .recomposeHighlighter()
                 .conditional(isEdit) {
                     aspectRatio(16f / 9f)
                 }
@@ -99,15 +98,13 @@ fun PhotoImage(
             success = { state, _ ->
                 val bitmap = state.imageBitmap?.asAndroidBitmap()
                 Box(
-                    modifier = modifier
-                        .recomposeHighlighter()
-                        .background(bitmap.majorColor(backgroundColor), shape),
+                    modifier = modifier.background(bitmap.majorColor(backgroundColor), shape),
                 ) {
                     ImageAny(
                         src = bitmap
                             ?.toDrawable()
                             ?.asPhoto(),
-                        modifier = modifier.recomposeHighlighter(),
+                        modifier = modifier,
                         alignment = alignment,
                         contentScale = contentScale,
                         alpha = alpha,

+ 2 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/ExoPlayerImpl.kt

@@ -57,7 +57,6 @@ import androidx.media3.ui.PlayerNotificationManager
 import androidx.media3.ui.PlayerView
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.LifecycleExt.rememberPlayPauseLifeCycleObserver
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ViewExt.controller
 import org.mjdev.tvlib.extensions.ViewExt.findView
 import org.mjdev.tvlib.ui.components.audiopreview.AudioPreview
@@ -71,7 +70,7 @@ class ExoPlayerImpl(
     override val context: Context,
 ) : IMediaPlayer, PlayerNotificationManager.MediaDescriptionAdapter, MediaSession.Callback {
 
-    private val requestCode :Int = 999
+    private val requestCode: Int = 999
 
     // todo : check activity
     private val pendingIntent: PendingIntent by lazy {
@@ -268,7 +267,6 @@ class ExoPlayerImpl(
         Box(
             modifier = Modifier
                 .fillMaxSize()
-                .recomposeHighlighter()
                 .onPreviewKeyEvent { ev ->
                     val controller = playerView.controller
                     if (controller?.isShown == true) {
@@ -282,9 +280,7 @@ class ExoPlayerImpl(
         ) {
             if (!isEdit) {
                 AndroidView(
-                    modifier = Modifier
-                        .fillMaxSize()
-                        .recomposeHighlighter(),
+                    modifier = Modifier.fillMaxSize(),
                     factory = {
                         playerView
                     }

+ 0 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/MediaPlayerContainer.kt

@@ -20,7 +20,6 @@ import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.RectangleShape
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.swipeGestures
 import org.mjdev.tvlib.ui.components.media.MediaPlayerState.Companion.rememberMediaPlayerState
 
@@ -47,7 +46,6 @@ fun MediaPlayerContainer(
                     )
                 }
                 .background(Color.Black, RectangleShape)
-                .recomposeHighlighter()
         ) {
             state.player.GetPlayerView()
 //            PlayerControlView(

+ 2 - 7
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/media/NativePlayerImpl.kt

@@ -36,7 +36,6 @@ import androidx.media3.common.VideoSize
 import androidx.media3.common.text.CueGroup
 import androidx.media3.common.util.Size
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 // todo
 @Suppress("unused", "DeprecatedCallableAddReplaceWith")
@@ -50,15 +49,11 @@ class NativePlayerImpl(
     override fun GetPlayerView() {
         val isEdit = isEditMode()
         Box(
-            modifier = Modifier
-                .fillMaxSize()
-                .recomposeHighlighter()
+            modifier = Modifier.fillMaxSize()
         ) {
             if (!isEdit) {
                 AndroidView(
-                    modifier = Modifier
-                        .fillMaxSize()
-                        .recomposeHighlighter(),
+                    modifier = Modifier.fillMaxSize(),
                     factory = { context ->
                         SurfaceView(context).apply {
                             mediaPlayer.setDisplay(holder)

+ 12 - 92
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavDrawerContent.kt

@@ -15,21 +15,16 @@ import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableIntState
 import androidx.compose.runtime.derivedStateOf
-import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.tv.material3.DrawerState
 import androidx.tv.material3.DrawerValue
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ModifierExt.onlyPortrait
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
-import org.mjdev.tvlib.extensions.NavControllerExt.open
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.navigation.MenuItem
 import org.mjdev.tvlib.navigation.NavHostControllerEx
@@ -39,41 +34,9 @@ import org.mjdev.tvlib.navigation.NavHostControllerEx
 @Previews
 @Composable
 fun NavDrawerContent(
-//    backgroundColor: Color = Color.DarkGray,
-//    shape: Shape = RoundedCornerShape(
-//        topStart = 0.dp,
-//        topEnd = 16.dp,
-//        bottomEnd = 16.dp,
-//        bottomStart = 0.dp
-//    ),
     navController: NavHostControllerEx = rememberNavControllerEx(),
-    onDrawerItemClick: (id: Int) -> Unit = { id ->
-        navController.menuItem(id).let { menuItem ->
-            if (menuItem.isAction) {
-                menuItem.menuAction?.invoke()
-            }
-            if (menuItem.isRoute) {
-                navController.open(menuItem.menuRoute)
-            }
-            if (menuItem.isPage) {
-                navController.onMenuItemClick(menuItem)
-            }
-        }
-    },
-    onDrawerItemFocus: (id: Int) -> Unit = { id ->
-        navController.menuItem(id).let { menuItem ->
-            if (menuItem.isPage) {
-                navController.onMenuItemClick(menuItem)
-            }
-        }
-    },
-    focusedIdx: MutableIntState = remember { mutableIntStateOf(-1) },
-    itemId: (menuItem: MenuItem) -> Int = { menuItem ->
-        navController.indexOfMenuItem(menuItem)
-    },
     // todo, padding
     minPortraitMenuWidth: Dp = 4.dp,
-    menuDrawerState: DrawerState = navController.menuDrawerState
 ) {
     val topItems = navController.menuItems.filter { mi ->
         mi.menuGravity == MenuItem.Gravity.Top
@@ -85,9 +48,9 @@ fun NavDrawerContent(
         mi.menuGravity == MenuItem.Gravity.Center
     }
     // todo
-    val paddingState = remember(menuDrawerState.currentValue) {
+    val paddingState = remember(navController.menuDrawerState.currentValue) {
         derivedStateOf {
-            when(menuDrawerState.currentValue) {
+            when (navController.menuDrawerState.currentValue) {
                 DrawerValue.Closed -> minPortraitMenuWidth
                 DrawerValue.Open -> 0.dp
             }
@@ -98,89 +61,46 @@ fun NavDrawerContent(
             .fillMaxHeight()
             .onlyPortrait {
                 widthIn(min = paddingState.value)
-            }
-            .recomposeHighlighter(),
+            },
     ) {
         Column(
-            modifier = Modifier
-                .fillMaxHeight()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxHeight(),
             verticalArrangement = Arrangement.Bottom,
             horizontalAlignment = Alignment.Start,
         ) {
             bottomItems.forEach { menuItem ->
                 if (menuItem.isEnabled) {
-                    val id = itemId(menuItem)
                     NavigationRow(
-                        id = id,
-                        focused = (focusedIdx.value == id),
-                        drawerState = navController.menuDrawerState,
-                        icon = menuItem.menuIcon,
-                        text = menuItem.menuText,
-                        onFocus = { focusId ->
-                            navController.openMenu()
-                            focusedIdx.value = focusId
-                            onDrawerItemFocus(focusId)
-                        },
-                        onClick = { clickId ->
-                            onDrawerItemClick(clickId)
-                        }
+                        menuItem = menuItem,
+                        navController = navController,
                     )
                 }
             }
         }
         Column(
-            modifier = Modifier
-                .fillMaxHeight()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxHeight(),
             verticalArrangement = Arrangement.Top,
             horizontalAlignment = Alignment.Start,
         ) {
             topItems.forEach { menuItem ->
                 if (menuItem.isEnabled) {
-                    val id = itemId(menuItem)
                     NavigationRow(
-                        id = id,
-                        focused = (focusedIdx.value == id),
-                        drawerState = navController.menuDrawerState,
-                        icon = menuItem.menuIcon,
-                        text = menuItem.menuText,
-                        onFocus = { focusId ->
-                            navController.openMenu()
-                            focusedIdx.value = focusId
-                            onDrawerItemFocus(focusId)
-                        },
-                        onClick = { clickId ->
-                            onDrawerItemClick(clickId)
-                        }
+                        menuItem = menuItem,
+                        navController = navController
                     )
                 }
             }
         }
         Column(
-            modifier = Modifier
-                .fillMaxHeight()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxHeight(),
             verticalArrangement = Arrangement.Center,
             horizontalAlignment = Alignment.Start,
         ) {
             centerItems.forEach { menuItem ->
                 if (menuItem.isEnabled) {
-                    val id = itemId(menuItem)
                     NavigationRow(
-                        id = id,
-                        focused = (focusedIdx.value == id),
-                        drawerState = navController.menuDrawerState,
-                        text = menuItem.menuText,
-                        icon = menuItem.menuIcon,
-                        onFocus = { focusId ->
-                            navController.openMenu()
-                            focusedIdx.value = focusId
-                            onDrawerItemFocus(focusId)
-                        },
-                        onClick = { clickId ->
-                            onDrawerItemClick(clickId)
-                        }
+                        menuItem = menuItem,
+                        navController = navController
                     )
                 }
             }

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

@@ -23,7 +23,6 @@ import androidx.compose.ui.layout.ContentScale
 import androidx.navigation.NavBackStackEntry
 import androidx.navigation.compose.NavHost
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.createGraph
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.extensions.NavGraphBuilderExt.screen
@@ -64,10 +63,10 @@ fun NavHostEx(
         contentScale = ContentScale.Crop
     )
     ScreenView(
-        modifier = modifier.recomposeHighlighter(),
+        modifier = modifier,
     ) {
         NavHost(
-            modifier = modifier.recomposeHighlighter(),
+            modifier = modifier,
             navController = navController,
             graph = remember(route, builder) {
                 navController.createGraph(

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

@@ -15,6 +15,7 @@ import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.navigationBarsPadding
 import androidx.compose.foundation.layout.statusBarsPadding
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.unit.Dp
@@ -27,7 +28,6 @@ import org.mjdev.tvlib.extensions.ComposeExt.isLandscapeMode
 import org.mjdev.tvlib.extensions.ComposeExt.isOpen
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
 import org.mjdev.tvlib.extensions.ModifierExt.onlyPortrait
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.navigation.MenuItem
 import org.mjdev.tvlib.navigation.NavHostControllerEx
@@ -45,7 +45,7 @@ fun Navigation(
         MenuItem.MENU_ITEM_SEARCH
     ) else listOf(),
     modal: Boolean = isPortraitMode(),
-    backgroundColor: Color = Color.DarkGray,
+    backgroundColor: Color = Color.Black.copy(alpha = 0.7f),
     navController: NavHostControllerEx = rememberNavControllerEx(menuItems),
     minPortraitMenuWidth: Dp = 4.dp,
     content: @Composable () -> Unit = { Page() },
@@ -53,9 +53,7 @@ fun Navigation(
     if (isEditMode()) navController.openMenu()
     val mainContent: @Composable () -> Unit = {
         Box(
-            modifier
-                .fillMaxSize()
-                .recomposeHighlighter()
+            modifier.fillMaxSize()
         ) {
             content()
         }
@@ -64,12 +62,9 @@ fun Navigation(
         Box(
             modifier = Modifier
                 .background(
-                    if (isLandscapeMode() || navController.menuDrawerState.isOpen)
-                        backgroundColor
-                    else
-                        Color.Transparent
+                    if (isLandscapeMode() || navController.menuDrawerState.isOpen)  backgroundColor
+                    else Color.Transparent
                 )
-                .recomposeHighlighter()
         ) {
             NavDrawerContent(
                 minPortraitMenuWidth = minPortraitMenuWidth,
@@ -85,7 +80,6 @@ fun Navigation(
                 // todo not working on lollipop
                 navigationBarsPadding().statusBarsPadding()
             }
-            .recomposeHighlighter()
     ) {
         SettingsDrawer(
             modifier = Modifier.fillMaxSize(),

+ 50 - 33
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/NavigationRow.kt

@@ -14,28 +14,26 @@ import androidx.compose.animation.fadeIn
 import androidx.compose.animation.fadeOut
 import androidx.compose.animation.shrinkVertically
 import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.AccountCircle
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
 import androidx.compose.ui.focus.FocusRequester
-import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.tv.material3.DrawerState
 import androidx.tv.material3.DrawerValue
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvlib.annotations.Previews
@@ -44,11 +42,13 @@ import org.mjdev.tvlib.extensions.ComposeExt.isFocused
 import org.mjdev.tvlib.extensions.ComposeExt.isLandscapeMode
 import org.mjdev.tvlib.extensions.ComposeExt.isOpen
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
-import org.mjdev.tvlib.extensions.ComposeExt.rememberDrawerState
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvlib.extensions.ModifierExt.focusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
+import org.mjdev.tvlib.extensions.NavControllerExt.open
+import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
+import org.mjdev.tvlib.navigation.MenuItem
+import org.mjdev.tvlib.navigation.NavHostControllerEx
 import org.mjdev.tvlib.ui.components.card.FocusHelper
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 import org.mjdev.tvlib.ui.components.icon.IconAny
@@ -60,9 +60,6 @@ import timber.log.Timber
 @Composable
 fun NavigationRow(
     modifier: Modifier = Modifier,
-    id: Int = -1,
-    text: Any? = "menu item 1",
-    icon: Any? = Icons.Default.AccountCircle,
     textColor: Color = Color.White,
     iconColor: Color = Color.White,
     focusedColor: Color = Color.Green,
@@ -73,16 +70,26 @@ fun NavigationRow(
     strokeWidth: Dp = 1.dp,
     margin: Dp = 0.dp,
     padding: Dp = 4.dp,
-    drawerState: DrawerState = rememberDrawerState(),
-    focused: Boolean = isEditMode(),
-    focusState: MutableState<FocusState?> = rememberFocusState(
-        text,
-        FocusHelper(focused)
-    ),
-    focusRequester: FocusRequester = rememberFocusRequester(id),
-    onFocus: (id: Int) -> Unit = {},
-    onClick: (id: Int) -> Unit = {},
+    navController: NavHostControllerEx = rememberNavControllerEx(),
+    menuItem: MenuItem = MenuItem.MENU_ITEM_EXIT,
 ) {
+    val id = navController.indexOfMenuItem(menuItem)
+    val focusRequester: FocusRequester = rememberFocusRequester()
+    val onDrawerItemFocus: () -> Unit = {
+        navController.menuItem(id).let { menuItem ->
+            if (menuItem.isPage) {
+                navController.onMenuItemClick(menuItem)
+            }
+        }
+    }
+    val onFocus: () -> Unit = {
+        navController.openMenu()
+        navController.selectedMenuItem.intValue = id
+        onDrawerItemFocus()
+    }
+    val drawerState = navController.menuDrawerState
+    val focused = (navController.selectedMenuItem.intValue == id)
+    val focusState = rememberFocusState(FocusHelper(focused))
     val isEdit = isEditMode()
     val isShown = isLandscapeMode() || drawerState.isOpen
     val isPortrait = isPortraitMode()
@@ -90,16 +97,27 @@ fun NavigationRow(
     else (fadeIn() + expandVertically())
     val exit = if (isPortrait) shrinkVertically()
     else (fadeOut() + shrinkVertically())
+    val onClick: () -> Unit = {
+        navController.menuItem(id).let { menuItem ->
+            if (menuItem.isAction) {
+                menuItem.menuAction?.invoke()
+            }
+            if (menuItem.isRoute) {
+                navController.open(menuItem.menuRoute)
+            }
+            if (menuItem.isPage) {
+                navController.onMenuItemClick(menuItem)
+            }
+        }
+    }
     if (isShown) {
         FocusableBox(
             modifier = modifier
-                .recomposeHighlighter()
                 .padding(margin)
                 .border(
                     BorderStroke(
                         strokeWidth,
-                        if (isEdit || focusState.isFocused) focusedColor
-                        else unFocusedColor
+                        if (isEdit || focused) focusedColor else unFocusedColor
                     ),
                     shape
                 )
@@ -110,27 +128,27 @@ fun NavigationRow(
             unFocusedColor = unFocusedColor,
             onFocusChange = { state ->
                 if (state.isFocused || state.hasFocus) {
-                    onFocus(id)
+                    onFocus()
                 }
             },
-            onClick = {
-                onClick(id)
-            },
+            onClick = { onClick() },
         ) {
             Row(
-                modifier = Modifier
-                    .recomposeHighlighter()
-                    .padding(padding),
+                modifier = Modifier.padding(padding),
                 horizontalArrangement = Arrangement.Start,
                 verticalAlignment = Alignment.CenterVertically,
             ) {
                 Box(
                     modifier = Modifier
                         .padding(4.dp)
-                        .recomposeHighlighter()
+                        .clip(CircleShape)
+                        .background(
+                            if (isEdit || focusState.isFocused) focusedColor else unFocusedColor,
+                            CircleShape
+                        )
                 ) {
                     IconAny(
-                        src = icon,
+                        src = menuItem.menuIcon,
                         contentDescription = null,
                         tint = iconColor
                     )
@@ -141,10 +159,9 @@ fun NavigationRow(
                     visible = (isEdit || (drawerState.currentValue == DrawerValue.Open))
                 ) {
                     TextAny(
-                        text = text,
+                        text = menuItem.menuText,
                         softWrap = false,
                         modifier = Modifier
-                            .recomposeHighlighter()
                             .padding(8.dp)
                             .width(expandedWidth),
                         color = textColor,

+ 0 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/navigation/SettingsDrawerContent.kt

@@ -20,7 +20,6 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 // todo not yet implemented
 @SuppressLint("AutoboxingStateValueProperty")
@@ -31,7 +30,6 @@ fun SettingsDrawerContent(
 ) {
     Column(
         modifier = modifier
-            .recomposeHighlighter()
             .fillMaxHeight()
             .conditional(isEditMode()) {
                 width(200.dp)

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

@@ -24,7 +24,6 @@ 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.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.requestFocusOnTouch
 import org.mjdev.tvlib.ui.components.complex.VerticalScrollableBox
 import org.mjdev.tvlib.ui.components.text.TextAny
@@ -44,24 +43,20 @@ open class Page {
     @CallSuper
     fun content() {
         Column(
-            Modifier
-                .fillMaxSize()
-                .recomposeHighlighter()
+            Modifier.fillMaxSize()
         ) {
             VerticalScrollableBox(
                 modifier = Modifier
                     .fillMaxSize()
                     .requestFocusOnTouch(
                         focusRequester = focusRequester
-                    )
-                    .recomposeHighlighter(),
+                    ),
                 contentAlignment = Alignment.Center,
             ) {
                 Box(
                     modifier = Modifier
                         .fillMaxSize()
-                        .focusRequester(focusRequester)
-                        .recomposeHighlighter(),
+                        .focusRequester(focusRequester),
                     contentAlignment = Alignment.Center
                 ) {
                     Content()
@@ -73,14 +68,12 @@ open class Page {
     @Composable
     open fun Content() {
         Column(
-            modifier = Modifier
-                .fillMaxSize()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxSize(),
             verticalArrangement = Arrangement.Center,
             horizontalAlignment = Alignment.CenterHorizontally,
         ) {
             TextAny(
-                modifier = Modifier.recomposeHighlighter(),
+                modifier = Modifier,
                 text = title ?: "Empty Page",
                 textAlign = TextAlign.Center,
                 fontSize = 32.sp,

+ 3 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/PagerScope.kt

@@ -34,9 +34,7 @@ class PagerScope(
         pages.invoke(this)
     }
 
-    fun menuItem(vararg item: MenuItem) {
-        navController.addMenuItem(*item)
-    }
+    fun menuItem(vararg item: MenuItem) = navController.addMenuItem(*item)
 
     fun page(
         page: Page,
@@ -46,6 +44,7 @@ class PagerScope(
         addUnique(page)
         if (isStartPage) {
             currentPage.value = size - 1
+            navController.selectedMenuItem.value = currentPage.value
         }
         page.let { p ->
             MenuItem(
@@ -62,9 +61,7 @@ class PagerScope(
     fun indexOfPage(page: Page?): Int {
         return if (page == null) return -1
         else {
-            indexOfFirst { p ->
-                p.toString() == page.toString()
-            }
+            indexOfFirst { p -> p.toString() == page.toString() }
         }
     }
 

+ 2 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/page/TvPager.kt

@@ -31,7 +31,6 @@ import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.navigation.MenuItemClickListener
 import org.mjdev.tvlib.navigation.MenuItem
@@ -48,12 +47,12 @@ fun TvPager(
     backGroundShape: Shape = RoundedCornerShape(roundCornerSize),
     @Suppress("UNUSED_ANONYMOUS_PARAMETER")
     onPageChange: (index: Int, page: Page?) -> Unit = { index, page -> },
+    navController: NavHostControllerEx = rememberNavControllerEx(),
     pages: PagerScope.() -> Unit = {
         page(EMPTY_PAGE)
     }
 ) {
 
-    val navController: NavHostControllerEx = rememberNavControllerEx()
     val currentPage = remember { mutableStateOf<Page?>(null) }
     val coroutineScope = rememberCoroutineScope()
     val pagerScope = rememberPagerScope(navController, startIndex, pages, onPageChange)
@@ -105,11 +104,9 @@ fun TvPager(
         },
         label = "TvPager"
     ) { pageIndex ->
-        val page = if (pagerScope.size > pageIndex) pagerScope[pageIndex]
-        else null
+        val page = if (pagerScope.size > pageIndex) pagerScope[pageIndex] else null
         Box(
             modifier = Modifier
-                .recomposeHighlighter()
                 .fillMaxSize()
                 .background(backGroundColor, backGroundShape),
         ) {

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

@@ -14,7 +14,6 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.navigation.NavHostControllerEx
 import org.mjdev.tvlib.ui.components.navigation.Navigation
@@ -29,9 +28,7 @@ fun ScreenView(
     content: @Composable () -> Unit = { Page() }
 ) {
     Box(
-        modifier = modifier
-            .fillMaxSize()
-            .recomposeHighlighter(),
+        modifier = modifier.fillMaxSize(),
         contentAlignment = Alignment.Center,
     ) {
         if (navController.menuState.value) {

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/AutoHideEmptyText.kt

@@ -25,7 +25,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.LocalTextStyle
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.textFrom
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @SuppressLint("ModifierParameter")
@@ -53,7 +52,7 @@ fun AutoHideEmptyText(
     if (textAny.isNotEmpty()) {
         TextAny(
             text,
-            modifier.recomposeHighlighter(),
+            modifier,
             color,
             fontSize,
             fontStyle,

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/CircleText.kt

@@ -31,7 +31,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.isPortraitMode
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.extensions.ModifierExt.tvAspectRatio
 
 @SuppressLint("ModifierParameter")
@@ -50,7 +49,7 @@ fun CircleText(
 ) {
     val isPortrait = isPortraitMode()
     Box(
-        modifier = modifier.recomposeHighlighter()
+        modifier = modifier
             .size(textSize.value.dp * 2)
             .padding(contentPadding)
             .tvAspectRatio(1f, !isPortrait)

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/TextAny.kt

@@ -26,7 +26,6 @@ import androidx.tv.material3.LocalTextStyle
 import androidx.tv.material3.Text
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.textFrom
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @SuppressLint("ModifierParameter")
@@ -51,7 +50,7 @@ fun TextAny(
     style: TextStyle = LocalTextStyle.current
 ) = Text(
     text = textFrom(text),
-    modifier = modifier.recomposeHighlighter(),
+    modifier = modifier,
     color = color,
     fontSize = fontSize,
     fontStyle = fontStyle,

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/text/TextWithShadow.kt

@@ -22,7 +22,6 @@ import androidx.compose.ui.unit.sp
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @Previews
@@ -44,7 +43,7 @@ fun TextWithShadow(
             shadowSize,
             shadowSize,
             shadowSize
-        ).recomposeHighlighter(),
+        ),
         style = MaterialTheme.typography.bodyMedium.copy(
             shadow = Shadow(
                 color = shadowColor,

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

@@ -31,7 +31,6 @@ fun AppUpdateAvailableMessage(
     githubRepository: String = "tvapp",
     backgroundColor: Color = Color(0, 132, 0, 255),
     buttonText: Any? = R.string.bt_update,
-    dismissState: MutableState<Boolean> = mutableStateOf(false),
     isDebug: Boolean = BuildConfig.DEBUG,
     appUpdater: AppUpdater = rememberAppUpdater(
         githubUser = githubUser,
@@ -40,13 +39,14 @@ fun AppUpdateAvailableMessage(
     ),
     isEdit: Boolean = isEditMode(),
     updateAvailable: State<Boolean> = appUpdater.isUpdateAvailable.collectAsState(false),
+    visibleState: MutableState<Boolean> = mutableStateOf(isEdit || updateAvailable.value),
     onButtonClick: () -> Unit = { appUpdater.updateApp() },
 ) = ErrorMessage(
-    visible = isEdit || updateAvailable.value,
     title = title,
     dismissText = buttonText,
     error = message.asException(),
     backgroundColor = backgroundColor,
     dismissible = true,
-    dismissOnClick = onButtonClick
+    dismissOnClick = onButtonClick,
+    visibleState=visibleState
 )

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

@@ -26,7 +26,6 @@ import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import kotlinx.coroutines.launch
 import org.mjdev.tvlib.BuildConfig
 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
@@ -68,9 +67,7 @@ fun BrowseView(
 ) {
     val coroutineScope = rememberCoroutineScope()
     ScrollableTvLazyColumn(
-        modifier = modifier
-            .fillMaxSize()
-            .recomposeHighlighter(),
+        modifier = modifier.fillMaxSize(),
         verticalArrangement = verticalArrangement,
         contentPadding = contentPadding,
         state = state
@@ -128,7 +125,7 @@ fun BrowseView(
         }
         if (isEdit || featuredItems.isNotEmpty()) item {
             BigCarousel(
-                modifier = Modifier.recomposeHighlighter(),
+                modifier = Modifier,
                 items = featuredItems,
                 onItemSelected = onItemFocused,
                 onItemClicked = onItemClicked,

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

@@ -33,7 +33,6 @@ import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.card.PhotoCard
 import org.mjdev.tvlib.ui.components.text.TextAny
 
@@ -66,13 +65,11 @@ fun CategoryRow(
     val scrollDelta = remember { mutableFloatStateOf(0f) }
     Column(
         modifier = Modifier
-            .recomposeHighlighter()
             .fillMaxWidth()
             .background(backgroundColor, backgroundShape)
     ) {
         TextAny(
             modifier = Modifier
-                .recomposeHighlighter()
                 .fillMaxWidth()
                 .padding(padding, padding / 2),
             text = title,
@@ -87,8 +84,7 @@ fun CategoryRow(
                     detectHorizontalDragGestures { _, dragAmount ->
                         scrollDelta.value = dragAmount
                     }
-                }
-                .recomposeHighlighter(),
+                },
             state = rowState,
             contentPadding = padding.value.dp,
         ) {

+ 5 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Clock.kt

@@ -36,7 +36,6 @@ import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ContextExt.dateAsString
 import org.mjdev.tvlib.extensions.ContextExt.timeAsString
 import org.mjdev.tvlib.extensions.ModifierExt.conditional
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 import org.mjdev.tvlib.ui.components.text.TextAny
 
@@ -92,7 +91,7 @@ fun Clock(
     }.collectAsState(initial = "1.1.1970") else null
 
     FocusableBox(
-        modifier = modifier.recomposeHighlighter()
+        modifier = modifier
             .padding(contentPadding)
             .conditional(isEdit) {
                 background(Color.DarkGray, RectangleShape)
@@ -102,19 +101,19 @@ fun Clock(
     ) {
 
         Box(
-            Modifier.recomposeHighlighter()
+            Modifier
                 .background(backgroundColor, RoundedCornerShape(roundSize))
                 .wrapContentSize()
                 .clip(RoundedCornerShape(roundSize))
         ) {
 
             Column(
-                modifier = Modifier.padding(8.dp, 2.dp, 8.dp, 2.dp).recomposeHighlighter(),
+                modifier = Modifier.padding(8.dp, 2.dp, 8.dp, 2.dp),
                 horizontalAlignment = horizontalAlignment,
             ) {
 
                 if (showTime) TextAny(
-                    modifier = modifier.wrapContentSize().recomposeHighlighter(),
+                    modifier = modifier.wrapContentSize(),
                     text = timeFlow?.value,
                     fontWeight = timeTextWeight,
                     fontSize = timeTextSize,
@@ -122,7 +121,7 @@ fun Clock(
                 )
 
                 if (showDate) TextAny(
-                    modifier = modifier.wrapContentSize().recomposeHighlighter(),
+                    modifier = modifier.wrapContentSize(),
                     text = dateFlow?.value,
                     textAlign = TextAlign.End,
                     fontWeight = dateTextWeight,

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

@@ -40,7 +40,6 @@ import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.computeCardWidth
 import org.mjdev.tvlib.extensions.CursorExt.getData
 import org.mjdev.tvlib.extensions.CursorExt.isNotEmpty
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.helpers.cursor.CachingCursor.Companion.rememberCursor
 import org.mjdev.tvlib.ui.components.card.PhotoCard
 import org.mjdev.tvlib.ui.components.text.TextAny
@@ -81,13 +80,11 @@ fun CursorRow(
     if (cursor?.isNotEmpty == true) {
         Column(
             modifier = Modifier
-                .recomposeHighlighter()
                 .fillMaxWidth()
                 .background(backgroundColor, backgroundShape)
         ) {
             TextAny(
                 modifier = Modifier
-                    .recomposeHighlighter()
                     .fillMaxWidth()
                     .padding(padding / 2, padding / 2),
                 text = title,
@@ -102,8 +99,7 @@ fun CursorRow(
                         detectHorizontalDragGestures { _, dragAmount ->
                             scrollDelta.value = dragAmount
                         }
-                    }
-                    .recomposeHighlighter(),
+                    },
                 state = rowState,
                 contentPadding = (padding.value * 1.3).dp, // todo due border & glow
             ) {

+ 24 - 17
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/ErrorMessage.kt

@@ -13,13 +13,17 @@ import androidx.compose.animation.EnterTransition
 import androidx.compose.animation.ExitTransition
 import androidx.compose.foundation.background
 import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.PaddingValues
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Divider
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.runtime.mutableStateOf
@@ -35,7 +39,6 @@ import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.ui.components.button.Button
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
@@ -51,9 +54,9 @@ fun ErrorMessage(
     dismissText: Any? = R.string.bt_dismiss,
     color: Color = Color.White,
     backgroundColor: Color = Color.Red,
-    fontSizeTitle: TextUnit = 18.sp,
-    fontSizeMessage: TextUnit = 12.sp,
-    fontSizeButton: TextUnit = 12.sp,
+    fontSizeTitle: TextUnit = 14.sp,
+    fontSizeMessage: TextUnit = 11.sp,
+    fontSizeButton: TextUnit = 11.sp,
     fontWeight: FontWeight = FontWeight.Bold,
     paddingTitle: Dp = 8.dp,
     paddingContent: Dp = 4.dp,
@@ -72,30 +75,36 @@ fun ErrorMessage(
     enter = enter,
     exit = exit
 ) {
-    BoxWithConstraints {
+    Box{
         Row(
             modifier = Modifier
-                .width(constraints.maxWidth.dp)
+                .fillMaxWidth()
                 .padding(paddingContent)
                 .border(borderSize, borderColor, backgroundShape)
-                .background(backgroundColor, backgroundShape)
-                .recomposeHighlighter(),
+                .background(backgroundColor, backgroundShape),
             verticalAlignment = Alignment.CenterVertically,
         ) {
             TextAny(
-                modifier = Modifier
-                    .padding(paddingTitle)
-                    .recomposeHighlighter(),
+                modifier = Modifier.padding(paddingTitle),
                 text = title ?: stringResource(id = R.string.title_error),
                 fontWeight = fontWeight,
                 fontSize = fontSizeTitle,
+                textAlign = TextAlign.Left,
+                maxLines = 1,
+                softWrap = false,
                 color = color
             )
+            Divider(
+                modifier = Modifier
+                    .width(1.dp)
+                    .height(24.dp),
+                color = Color.White
+            )
             TextAny(
                 modifier = Modifier
                     .fillMaxWidth()
                     .weight(1f)
-                    .recomposeHighlighter(),
+                    .padding(start = 8.dp),
                 color = color,
                 fontSize = fontSizeMessage,
                 fontWeight = fontWeight,
@@ -106,13 +115,11 @@ fun ErrorMessage(
             )
             if (dismissible && (dismissText != null)) {
                 Button(
-                    modifier = Modifier
-                        .padding(4.dp)
-                        .recomposeHighlighter(),
+                    modifier = Modifier.padding(8.dp, 8.dp),
                     text = dismissText,
                     fontSize = fontSizeButton,
-                    contentPadding = PaddingValues(8.dp, 0.dp),
-                    containerColor = Color.Black.copy(alpha = 0.2f),
+                    contentPadding = PaddingValues(8.dp, 2.dp),
+                    containerColor = Color.White.copy(alpha = 0.2f),
                     onClick = {
                         visibleState.value = false
                         dismissOnClick.invoke()

+ 4 - 17
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Header.kt

@@ -31,7 +31,6 @@ import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 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
@@ -61,24 +60,19 @@ fun Header(
     val isPortrait = isPortraitMode()
     Box(
         modifier = Modifier
-            .recomposeHighlighter()
             .fillMaxWidth()
             .background(backgroundColor, RoundedCornerShape(roundSize))
             .padding(padding),
         contentAlignment = Alignment.Center
     ) {
         Row(
-            modifier = Modifier
-                .fillMaxWidth()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxWidth(),
             horizontalArrangement = Arrangement.End,
             verticalAlignment = Alignment.CenterVertically,
         ) {
             if (!isPortrait) {
                 Clock(
-                    modifier = Modifier
-                        .wrapContentSize()
-                        .recomposeHighlighter(),
+                    modifier = Modifier.wrapContentSize(),
                     backgroundColor = Color.Black.copy(alpha = 0.2f),
                     contentPadding = contentPadding,
                     timeTextColor = color,
@@ -89,7 +83,6 @@ fun Header(
             if (isEdit || (messagesCount > 0)) {
                 Badge(
                     modifier = Modifier
-                        .recomposeHighlighter()
                         .wrapContentSize()
                         .clip(CircleShape),
                     contentPadding = contentPadding,
@@ -103,7 +96,6 @@ fun Header(
             }
             UserPic(
                 modifier = Modifier
-                    .recomposeHighlighter()
                     .size(56.dp)
                     .clip(CircleShape),
                 src = userIcon,
@@ -114,15 +106,12 @@ fun Header(
             )
         }
         Row(
-            modifier = Modifier
-                .fillMaxWidth()
-                .recomposeHighlighter(),
+            modifier = Modifier.fillMaxWidth(),
             horizontalArrangement = Arrangement.Start,
             verticalAlignment = Alignment.CenterVertically,
         ) {
             FocusableBox(
                 modifier = Modifier
-                    .recomposeHighlighter()
                     .wrapContentHeight()
                     .width(0.01.dp),
                 onFocusChange = { state ->
@@ -132,9 +121,7 @@ fun Header(
                 }
             )
             Title(
-                modifier = Modifier
-                    .wrapContentSize()
-                    .recomposeHighlighter(),
+                modifier = Modifier.wrapContentSize(),
                 title = title ?: R.string.app_name,
                 icon = appIcon,
                 fontWeight = fontWeight,

+ 3 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/NetworkErrorMessage.kt

@@ -38,5 +38,7 @@ fun NetworkErrorMessage(
     visible = isEdit || networkState.isNotConnected,
     error = message.asException(),
     backgroundColor = backgroundColor,
-    dismissible = dismissible
+    dismissible = dismissible,
+    enter = enter,
+    exit = exit
 )

+ 4 - 8
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/ScrollableTvLazyColumn.kt

@@ -23,7 +23,6 @@ import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import org.mjdev.tvlib.annotations.Previews
 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.ui.components.complex.VerticalScrollableBox
 
 @Previews
@@ -45,16 +44,13 @@ fun ScrollableTvLazyColumn(
         modifier = modifier
             .conditional(isEdit) {
                 fillMaxSize()
-            }
-            .recomposeHighlighter(),
+            },
         state = state
     ) {
         TvLazyColumn(
-            modifier = modifier
-                .conditional(isEdit) {
-                    fillMaxSize()
-                }
-                .recomposeHighlighter(),
+            modifier = modifier.conditional(isEdit) {
+                fillMaxSize()
+            },
             state = state,
             contentPadding = contentPadding,
             reverseLayout = reverseLayout,

+ 1 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/TVRow.kt

@@ -22,7 +22,6 @@ import androidx.tv.foundation.lazy.list.TvLazyListState
 import androidx.tv.foundation.lazy.list.TvLazyRow
 import androidx.tv.foundation.lazy.list.rememberTvLazyListState
 import org.mjdev.tvlib.annotations.Previews
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 
 @Previews
 @Composable
@@ -39,7 +38,7 @@ fun TVRow(
     content: TvLazyListScope.() -> Unit = {}
 ) {
     TvLazyRow(
-        modifier = modifier.recomposeHighlighter(),
+        modifier = modifier,
         state = state,
         contentPadding = PaddingValues(contentPadding * 2, contentPadding),
         reverseLayout = reverseLayout,

+ 13 - 18
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Tabs.kt

@@ -15,8 +15,10 @@ import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.width
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
@@ -33,7 +35,6 @@ import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.extensions.ComposeExt.isFocused
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvlib.extensions.ComposeExt.rememberMutableInteractionSource
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.interfaces.ItemWithTitle
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
 import org.mjdev.tvlib.ui.components.text.TextAny
@@ -53,7 +54,7 @@ fun Tabs(
     interactionSource: MutableInteractionSource = rememberMutableInteractionSource(items),
     onItemClick: (item: Any?) -> Unit = {}
 ) {
-    val selectedTabIndex = remember { mutableIntStateOf(0) }
+    var selectedTabIndex by remember { mutableIntStateOf(0) }
     val colors = TabDefaults.pillIndicatorTabColors(
         contentColor = activeContentColor,
         inactiveContentColor = activeContentColor.copy(alpha = 0.4f),
@@ -65,18 +66,14 @@ fun Tabs(
         disabledSelectedContentColor = selectedContentColor,
     )
     TabRow(
-        modifier = modifier
-            .fillMaxWidth()
-            .recomposeHighlighter(),
-        selectedTabIndex = selectedTabIndex.value,
+        modifier = modifier.fillMaxWidth(),
+        selectedTabIndex = selectedTabIndex,
         contentColor = activeContentColor,
         separator = {
             Spacer(modifier = Modifier.width(itemsSpacing))
         },
         indicator = { tabPositions, doesTabRowHaveFocus ->
-            tabPositions.getOrNull(
-                selectedTabIndex.value
-            )?.let { tab ->
+            tabPositions.getOrNull(selectedTabIndex)?.let { tab ->
                 TabRowDefaults.PillIndicator(
                     currentTabPosition = tab,
                     doesTabRowHaveFocus = doesTabRowHaveFocus,
@@ -88,14 +85,14 @@ fun Tabs(
     ) {
         items.forEachIndexed { index, tab ->
             Tab(
-                modifier = Modifier.recomposeHighlighter(),
+                modifier = Modifier,
                 colors = colors,
-                selected = index == selectedTabIndex.value,
+                selected = index == selectedTabIndex,
                 onFocus = {
-                    selectedTabIndex.value = index
+                    selectedTabIndex = index
                 },
                 onClick = {
-                    onItemClick(selectedTabIndex.value)
+                    onItemClick(selectedTabIndex)
                 },
                 interactionSource = interactionSource
             ) {
@@ -105,15 +102,13 @@ fun Tabs(
                     focusState = focusState,
                     onFocusChange = {
                         if (focusState.isFocused) {
-                            selectedTabIndex.value = index
+                            selectedTabIndex = index
                         }
                     },
-                    onClick = { onItemClick(items[selectedTabIndex.value]) }
+                    onClick = { onItemClick(items[selectedTabIndex]) }
                 ) {
                     TextAny(
-                        modifier = Modifier
-                            .padding(horizontal = 16.dp, vertical = 8.dp)
-                            .recomposeHighlighter(),
+                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
                         text = if (tab is ItemWithTitle<*>) tab.title else tab.toString(),
                         fontSize = fontSize,
                         color = Color.White,

+ 3 - 7
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/Title.kt

@@ -28,7 +28,6 @@ import androidx.compose.ui.unit.sp
 import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 import org.mjdev.tvlib.extensions.ComposeExt.isFocused
 import org.mjdev.tvlib.extensions.ComposeExt.rememberFocusState
-import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 import org.mjdev.tvlib.R
 import org.mjdev.tvlib.annotations.Previews
 import org.mjdev.tvlib.ui.components.complex.FocusableBox
@@ -53,7 +52,7 @@ fun Title(
     val focusState = rememberFocusState(title)
     val shadowColor = if (isEdit || focusState.isFocused) focusShadowColor else unfocusedShadowColor
     FocusableBox(
-        modifier = modifier.recomposeHighlighter(),
+        modifier = modifier,
         onClick = onClick,
         shape = RoundedCornerShape(8.dp),
         focusedColor = Color.Transparent,
@@ -62,14 +61,11 @@ fun Title(
         }
     ) {
         Row(
-            modifier = modifier
-                .padding(16.dp, 8.dp, 8.dp, 8.dp)
-                .recomposeHighlighter(),
+            modifier = modifier.padding(16.dp, 8.dp, 8.dp, 8.dp),
             verticalAlignment = CenterVertically,
         ) {
             CircleImage(
                 modifier = Modifier
-                    .recomposeHighlighter()
                     .height((fontSize.value).dp)
                     .aspectRatio(1f)
                     .scale(1.3f)
@@ -86,7 +82,7 @@ fun Title(
                 src = icon
             )
             TextWithShadow(
-                modifier = modifier.recomposeHighlighter(),
+                modifier = modifier,
                 shadowColor = shadowColor,
                 shadowSize = shadowSize,
                 text = title ?: R.string.app_name,

+ 3 - 5
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/tv/UserPic.kt

@@ -21,7 +21,6 @@ import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.MaterialTheme
 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.ui.components.complex.FocusableBox
@@ -46,10 +45,9 @@ fun UserPic(
 ) {
     val isEdit = isEditMode()
     CircleImage(
-        modifier = modifier.recomposeHighlighter()
-            .conditional(isEdit) {
-                size(64.dp)
-            },
+        modifier = modifier.conditional(isEdit) {
+            size(64.dp)
+        },
         backGroundColor = backGroundColor,
         borderSize = borderSize,
         borderColor = borderColor,