Milan Jurkulak 3 лет назад
Родитель
Сommit
85fbd3363b

+ 12 - 26
app/src/main/kotlin/org/mjdev/tvapp/base/extensions/ModifierExt.kt

@@ -9,7 +9,7 @@
 package org.mjdev.tvapp.base.extensions
 
 import android.annotation.SuppressLint
-import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.clickable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
@@ -17,11 +17,9 @@ 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.input.pointer.pointerInput
 import org.mjdev.tvapp.base.extensions.ComposeExt.isFocused
 import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusRequester
 import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusState
-import timber.log.Timber
 
 object ModifierExt {
 
@@ -29,7 +27,7 @@ object ModifierExt {
         condition: Boolean,
         other: Modifier.() -> Modifier
     ): Modifier {
-        return when(condition) {
+        return when (condition) {
             true -> this.then(other.invoke(this))
             else -> this
         }
@@ -39,36 +37,24 @@ object ModifierExt {
     @Composable
     // todo focus problem, requester not registered
     fun Modifier.touchable(
-        state: MutableState<FocusState?> = rememberFocusState(),
+        focusState: MutableState<FocusState?> = rememberFocusState(),
         focusRequester: FocusRequester = rememberFocusRequester(),
         onFocus: FocusRequester.() -> Unit = {},
         onClick: FocusRequester.() -> Unit = {},
-    ): Modifier = focusRequester(
+    ): Modifier = this then focusRequester(
         focusRequester
-    ).pointerInput(Unit) {
-        detectTapGestures {
-            if (state.isFocused) {
-                onClick(focusRequester)
-            } else {
-                try {
-                    focusRequester.requestFocus()
-                    onFocus(focusRequester)
-                } catch (e: Exception) {
-                    Timber.e(e)
-                }
+    ).onFocusChanged { state ->
+            focusState.value = state
+            if (focusState.isFocused) {
+                onFocus(focusRequester)
             }
         }
-    }.onFocusChanged { fstate ->
-        state.value = fstate
-        onFocus(focusRequester)
-    }.apply {
-        if (state.isFocused) {
-            try {
+        .clickable {
+            if (focusState.isFocused) {
+                onClick(focusRequester)
+            } else {
                 focusRequester.requestFocus()
-            } catch (e: Exception) {
-                Timber.e(e)
             }
         }
-    }
 
 }

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/button/Button.kt

@@ -65,7 +65,7 @@ fun Button(
     Button(
         modifier = modifier
             .touchable(
-                state = focusState,
+                focusState = focusState,
             )
             .border(BorderStroke(borderSize, borderColor), shape),
         glow = glow,

+ 12 - 39
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/card/CarouselCard.kt

@@ -9,31 +9,22 @@
 package org.mjdev.tvapp.base.ui.components.card
 
 import android.annotation.SuppressLint
-import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.layout.defaultMinSize
-import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusState
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import androidx.tv.material3.CardDefaults
 import androidx.tv.material3.CardScale
-import androidx.tv.material3.CompactCard
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvapp.base.extensions.ComposeExt.isEditMode
 import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvapp.base.extensions.ModifierExt.conditional
-import org.mjdev.tvapp.base.extensions.ModifierExt.touchable
 import org.mjdev.tvapp.base.interfaces.ItemWithBackground
 import org.mjdev.tvapp.base.interfaces.ItemWithDescription
-import org.mjdev.tvapp.base.interfaces.ItemWithSubtitle
-import org.mjdev.tvapp.base.interfaces.ItemWithTitle
 import org.mjdev.tvapp.base.ui.components.image.ImageAny
-import org.mjdev.tvapp.base.ui.components.text.TextAny
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @Preview
@@ -59,37 +50,19 @@ fun CarouselCard(
     onClick: () -> Unit = {}
 ) {
     val isEdit = isEditMode()
-    CompactCard(
-        modifier = modifier
-            .touchable(
-                state = focusState,
-                onClick = { onClick() },
-                onFocus = { onFocus() },
-            )
-            .conditional(isEdit) {
-                aspectRatio(16f / 9f).defaultMinSize(260.dp)
-            },
-        border = CardDefaults.colorFocusBorder(Color.Green),
-        scale = scale,
-        image = {
-            imageRenderer(modifier)
-        },
-        title = {
-            TextAny(
-                modifier = Modifier.padding(4.dp),
-                text = (item as? ItemWithTitle)?.title
-            )
-        },
-        subtitle = {
-            TextAny(
-                modifier = Modifier.padding(4.dp),
-                text = (item as? ItemWithSubtitle)?.subtitle
-            )
+    PhotoCard(
+        item = item,
+        modifier = modifier.conditional(isEdit) {
+            defaultMinSize(260.dp)
         },
-        description = {
-            // todo
-        },
-        onClick = onClick
+        aspectRatio = null,
+        contentScale = contentScale,
+        scale = scale,
+        focusState = focusState,
+        placeholder = placeholder,
+        imageRenderer = imageRenderer,
+        onFocus = { onFocus() },
+        onClick = { onClick() }
     )
 
 }

+ 3 - 4
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/card/ItemCard.kt

@@ -9,7 +9,6 @@
 package org.mjdev.tvapp.base.ui.components.card
 
 import android.annotation.SuppressLint
-import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.layout.widthIn
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
@@ -46,6 +45,7 @@ fun ItemCard(
     border: CardBorder = CardDefaults.colorFocusBorder(Color.Green),
     glow: CardGlow = CardDefaults.colorFocusGlow(Color.Green),
     placeholder: @Composable () -> Unit = {},
+    aspectRatio: Float? = 16f / 9f,
     imageRenderer: @Composable (modifier: Modifier) -> Unit = {
         ImageAny(
             modifier = modifier,
@@ -59,9 +59,8 @@ fun ItemCard(
     onFocus: (item: Any?) -> Unit = {},
     onClick: (item: Any?) -> Unit = {},
 ) = FocusableCard(
-    modifier = modifier
-        .widthIn(max = 320.dp)
-        .aspectRatio(16f / 9f),
+    modifier = modifier.widthIn(max = 320.dp),
+    aspectRatio = aspectRatio,
     item = item,
     focusState = focusState,
     contentScale = contentScale,

+ 17 - 13
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/card/PhotoCard.kt

@@ -18,7 +18,7 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.tv.material3.CardDefaults
 import androidx.tv.material3.CardScale
 import androidx.tv.material3.ExperimentalTvMaterial3Api
-import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusState
+import org.mjdev.tvapp.base.extensions.ComposeExt
 import org.mjdev.tvapp.base.interfaces.ItemWithDescription
 import org.mjdev.tvapp.base.interfaces.ItemWithImage
 import org.mjdev.tvapp.base.ui.components.image.PhotoImage
@@ -31,6 +31,7 @@ fun PhotoCard(
     item: Any? = null,
     modifier: Modifier = Modifier,
     contentScale: ContentScale = ContentScale.Crop,
+    focusState: MutableState<FocusState?> = ComposeExt.rememberFocusState(),
     imageRenderer: @Composable (modifier: Modifier) -> Unit = { m ->
         PhotoImage(
             modifier = m,
@@ -38,19 +39,22 @@ fun PhotoCard(
             contentDescription = (item as? ItemWithDescription)?.description?.toString(),
         )
     },
+    aspectRatio: Float? = 16f / 9f,
     placeholder: @Composable () -> Unit = {},
     scale: CardScale = CardDefaults.scale(),
-    focusState: MutableState<FocusState?> = rememberFocusState(),
     onFocus: (item: Any?) -> Unit = {},
     onClick: (item: Any?) -> Unit = {},
-) = ItemCard(
-    item = item,
-    modifier = modifier,
-    focusState = focusState,
-    contentScale = contentScale,
-    scale = scale,
-    imageRenderer = imageRenderer,
-    placeholder = placeholder,
-    onClick = onClick,
-    onFocus = onFocus
-)
+)  {
+    ItemCard(
+        item = item,
+        modifier  = modifier,
+        focusState = focusState,
+        contentScale = contentScale,
+        aspectRatio=aspectRatio,
+        scale = scale,
+        imageRenderer = imageRenderer,
+        placeholder = placeholder,
+        onClick = onClick,
+        onFocus = onFocus
+    )
+}

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/complex/FocusableBox.kt

@@ -50,7 +50,7 @@ fun FocusableBox(
     Surface(
         onClick = onClick,
         modifier = modifier.touchable(
-            state = focusState,
+            focusState = focusState,
             onFocus = { onFocus() },
             onClick = { onClick() },
         ),

+ 17 - 6
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/complex/FocusableCard.kt

@@ -9,13 +9,16 @@
 package org.mjdev.tvapp.base.ui.components.complex
 
 import android.annotation.SuppressLint
+import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.aspectRatio
 import androidx.compose.foundation.layout.defaultMinSize
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
+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.graphics.Color
 import androidx.compose.ui.layout.ContentScale
@@ -30,9 +33,9 @@ import androidx.tv.material3.CardShape
 import androidx.tv.material3.CompactCard
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvapp.base.extensions.ComposeExt
+import org.mjdev.tvapp.base.extensions.ComposeExt.isFocused
 import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvapp.base.extensions.ModifierExt.conditional
-import org.mjdev.tvapp.base.extensions.ModifierExt.touchable
 import org.mjdev.tvapp.base.interfaces.ItemWithDescription
 import org.mjdev.tvapp.base.interfaces.ItemWithImage
 import org.mjdev.tvapp.base.interfaces.ItemWithSubtitle
@@ -66,10 +69,12 @@ fun FocusableCard(
             placeholder = placeholder
         )
     },
+    aspectRatio: Float? = 16f / 9f,
     onFocus: (item: Any?) -> Unit = {},
     onClick: (item: Any?) -> Unit = {},
 ) {
     val isEdit = ComposeExt.isEditMode()
+    val focusRequester = FocusRequester()
     CompactCard(
         scale = scale,
         shape = shape,
@@ -77,17 +82,23 @@ fun FocusableCard(
         border = border,
         glow = glow,
         modifier = modifier
+            .conditional(aspectRatio != null) {
+                aspectRatio(aspectRatio!!)
+            }
             .conditional(isEdit) {
                 aspectRatio(16f / 9f).defaultMinSize(80.dp)
             }
             .onFocusChanged { state ->
                 focusState.value = state
             }
-            .touchable(
-                state = focusState,
-                onClick = { onClick(item) },
-                onFocus = { onFocus(item) }
-            ),
+            .focusRequester(focusRequester)
+            .clickable {
+                if (focusState.isFocused) {
+                    onClick(item)
+                } else {
+                    focusRequester.requestFocus()
+                }
+            },
         image = {
             imageRenderer(modifier)
         },