ソースを参照

responsive design improvements

Milan Jurkulak 3 年 前
親
コミット
3b9e608356

+ 1 - 1
app/build.gradle.kts

@@ -145,7 +145,7 @@ dependencies {
     // image loading
     implementation("io.coil-kt:coil-compose:2.4.0")
     implementation("com.github.skydoves:landscapist-coil:2.2.2")
-    // constraint layout
+    // constraint layout // todo remove
     implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")
     // debug
     implementation("com.jakewharton.timber:timber:5.0.1")

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

@@ -9,13 +9,11 @@
 package org.mjdev.tvapp.base.ui.components.card
 
 import android.annotation.SuppressLint
-import androidx.compose.foundation.layout.widthIn
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 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.CardBorder
 import androidx.tv.material3.CardColors
 import androidx.tv.material3.CardDefaults
@@ -55,7 +53,7 @@ fun ItemCard(
     },
     onClick: (item: Any?) -> Unit = {},
 ) = FocusableCard(
-    modifier = modifier.widthIn(max = 320.dp),
+    modifier = modifier,
     item = item,
     contentScale = contentScale,
     scale = scale,

+ 7 - 6
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/carousel/BigCarousel.kt

@@ -9,6 +9,7 @@
 package org.mjdev.tvapp.base.ui.components.carousel
 
 import android.annotation.SuppressLint
+import android.content.res.Configuration
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
@@ -27,8 +28,6 @@ import androidx.tv.material3.CardScale
 import androidx.tv.material3.Carousel
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import org.mjdev.tvapp.base.extensions.ComposeExt
-import org.mjdev.tvapp.base.extensions.ComposeExt.isEditMode
-import org.mjdev.tvapp.base.ui.components.card.CarouselCard
 
 // todo swipe left and swipe right
 @SuppressLint("AutoboxingStateValueProperty")
@@ -41,8 +40,10 @@ fun BigCarousel(
     onItemSelected: (movie: Any?) -> Unit = {},
     onItemClicked: (movie: Any?) -> Unit = {},
 ) {
-    val isEdit = isEditMode()
-    val height = if (isEdit) 128.dp else (LocalConfiguration.current.screenHeightDp / 2).dp
+    val height = LocalConfiguration.current.let { config ->
+        if (config.orientation == Configuration.ORIENTATION_PORTRAIT) config.screenWidthDp * 0.4f
+        else config.screenHeightDp * 0.4f
+    }
     val focusState: MutableState<FocusState?> = ComposeExt.rememberFocusState()
     val itemIndex = remember { mutableIntStateOf(0) }
     val selectedItem: () -> Any? = { items[itemIndex.value] }
@@ -51,14 +52,14 @@ fun BigCarousel(
             itemCount = items.size,
             modifier = modifier
                 .fillMaxWidth()
-                .height(height),
+                .height(height.dp),
         ) { indexOfCarouselItem ->
             itemIndex.value = indexOfCarouselItem
             CarouselCard(
                 item = items[indexOfCarouselItem],
                 modifier = modifier
                     .fillMaxWidth()
-                    .height(height)
+                    .height(height.dp)
                     .onFocusChanged { state ->
                         if (state.isFocused || state.hasFocus) {
                             onItemSelected(selectedItem())

+ 6 - 5
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/card/CarouselCard.kt → app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/carousel/CarouselCard.kt

@@ -1,12 +1,12 @@
 /*
  * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
+ *  Contact:
+ *  e: mimoccc@gmail.com
+ *  e: mj@mjdev.org
+ *  w: https://mjdev.org
  */
 
-package org.mjdev.tvapp.base.ui.components.card
+package org.mjdev.tvapp.base.ui.components.carousel
 
 import android.annotation.SuppressLint
 import androidx.compose.foundation.layout.defaultMinSize
@@ -24,6 +24,7 @@ import org.mjdev.tvapp.base.extensions.ComposeExt.rememberFocusState
 import org.mjdev.tvapp.base.extensions.ModifierExt.conditional
 import org.mjdev.tvapp.base.interfaces.ItemWithBackground
 import org.mjdev.tvapp.base.interfaces.ItemWithDescription
+import org.mjdev.tvapp.base.ui.components.card.PhotoCard
 import org.mjdev.tvapp.base.ui.components.image.ImageAny
 
 @OptIn(ExperimentalTvMaterial3Api::class)

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

@@ -9,8 +9,10 @@
 package org.mjdev.tvapp.base.ui.components.complex
 
 import android.annotation.SuppressLint
+import android.content.res.Configuration.ORIENTATION_PORTRAIT
 import androidx.compose.foundation.layout.defaultMinSize
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
@@ -19,6 +21,7 @@ import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.tv.material3.CardBorder
@@ -73,6 +76,10 @@ fun FocusableCard(
     onClick: (item: Any?) -> Unit = {},
 ) {
     val isEdit = ComposeExt.isEditMode()
+    val width = LocalConfiguration.current.let { config ->
+        if (config.orientation == ORIENTATION_PORTRAIT) config.screenWidthDp * 0.5f
+        else config.screenHeightDp * 0.5f
+    }
     CompactCard(
         scale = scale,
         shape = shape,
@@ -80,6 +87,7 @@ fun FocusableCard(
         border = border,
         glow = glow,
         modifier = modifier
+            .width(width.dp)
             .focusState(focusState)
             .onFocusChanged { state ->
                 onFocusChange(state)

+ 2 - 2
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/tv/CategoryRow.kt

@@ -10,8 +10,8 @@ package org.mjdev.tvapp.base.ui.components.tv
 
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
@@ -44,7 +44,7 @@ fun CategoryRow(
     )
     TVRow(
         horizontalArrangement = Arrangement.spacedBy(16.dp),
-        modifier = Modifier.height(200.dp),
+        modifier = Modifier.wrapContentSize(),
         contentPadding = 16.dp,
     ) {
         items(items) { item ->

+ 59 - 68
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/tv/Header.kt

@@ -9,6 +9,9 @@
 package org.mjdev.tvapp.base.ui.components.tv
 
 import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
@@ -16,6 +19,7 @@ import androidx.compose.foundation.layout.wrapContentSize
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
@@ -24,15 +28,14 @@ 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 androidx.constraintlayout.compose.ConstraintLayout
 import org.mjdev.tvapp.R
 import org.mjdev.tvapp.base.annotations.TvPreview
+import org.mjdev.tvapp.base.extensions.ComposeExt.isEditMode
 import org.mjdev.tvapp.base.ui.components.badge.Badge
 
 @TvPreview
 @Composable
 fun Header(
-    modifier: Modifier = Modifier,
     title: Any? = R.string.app_name,
     fontSize: TextUnit = 24.sp,
     fontWeight: FontWeight = FontWeight.Bold,
@@ -47,75 +50,63 @@ fun Header(
     onMessageBadgeClick: () -> Unit = {},
     onUserPicClick: () -> Unit = {},
 ) {
-
-    ConstraintLayout(
-        modifier = modifier
+    val isEdit = isEditMode()
+    Box(
+        modifier = Modifier
             .fillMaxWidth()
             .background(backgroundColor, RoundedCornerShape(roundSize))
             .padding(padding + roundSize)
     ) {
-
-        val (_title, _clock, _badge, _settings) = createRefs()
-
-        Title(
-            modifier = Modifier.constrainAs(_title) {
-                top.linkTo(parent.top)
-                start.linkTo(parent.start)
-                bottom.linkTo(parent.bottom)
-            },
-            title = title ?: R.string.app_name,
-            fontWeight = fontWeight,
-            fontSize = fontSize,
-            color = color,
-            onClick = onTitleClick,
-        )
-
-        Clock(
-            modifier = Modifier.constrainAs(_clock) {
-                top.linkTo(parent.top)
-                end.linkTo(_badge.start)
-                bottom.linkTo(parent.bottom)
-            },
-            backgroundColor = Color.Black.copy(alpha = 0.2f),
-            contentPadding = contentPadding,
-            timeTextColor = color,
-            dateTextColor = color,
-            onClick = onClockClick,
-        )
-
-        Badge(
-            modifier = Modifier
-                .constrainAs(_badge) {
-                    top.linkTo(parent.top)
-                    end.linkTo(_settings.start)
-                    bottom.linkTo(parent.bottom)
-                }
-                .wrapContentSize()
-                .clip(CircleShape),
-            contentPadding = contentPadding,
-            count = messagesCount,
-            borderColor = Color.White,
-            borderSize = 1.dp,
-            textSize = 20.sp,
-            textColor = Color.White,
-            onClick = onMessageBadgeClick,
-        )
-
-        UserPic(
-            modifier = Modifier
-                .size(56.dp)
-                .constrainAs(_settings) {
-                    top.linkTo(parent.top)
-                    end.linkTo(parent.end)
-                    bottom.linkTo(parent.bottom)
-                }
-                .clip(CircleShape),
-            borderColor = Color.White,
-            contentPadding = contentPadding,
-            borderSize = 1.dp,
-            onClick = onUserPicClick,
-        )
-
+        Row(
+            modifier = Modifier.fillMaxWidth(),
+            horizontalArrangement = Arrangement.End,
+            verticalAlignment = Alignment.CenterVertically,
+        ) {
+            Clock(
+                modifier = Modifier.wrapContentSize(),
+                backgroundColor = Color.Black.copy(alpha = 0.2f),
+                contentPadding = contentPadding,
+                timeTextColor = color,
+                dateTextColor = color,
+                onClick = onClockClick,
+            )
+            if (isEdit || (messagesCount > 0)) {
+                Badge(
+                    modifier = Modifier
+                        .wrapContentSize()
+                        .clip(CircleShape),
+                    contentPadding = contentPadding,
+                    count = messagesCount,
+                    borderColor = Color.White,
+                    borderSize = 1.dp,
+                    textSize = 20.sp,
+                    textColor = Color.White,
+                    onClick = onMessageBadgeClick,
+                )
+            }
+            UserPic(
+                modifier = Modifier
+                    .size(56.dp)
+                    .clip(CircleShape),
+                borderColor = Color.White,
+                contentPadding = contentPadding,
+                borderSize = 1.dp,
+                onClick = onUserPicClick,
+            )
+        }
+        Row(
+            modifier = Modifier.fillMaxWidth(),
+            horizontalArrangement = Arrangement.Start,
+            verticalAlignment = Alignment.CenterVertically,
+        ) {
+            Title(
+                modifier = Modifier.wrapContentSize(),
+                title = title ?: R.string.app_name,
+                fontWeight = fontWeight,
+                fontSize = fontSize,
+                color = color,
+                onClick = onTitleClick,
+            )
+        }
     }
-
 }