Ver código fonte

code improvements

Milan Jurkulak 2 anos atrás
pai
commit
f85afe13a4

+ 14 - 0
app/src/main/kotlin/org/mjdev/tvapp/ui/screens/SplashScreen.kt

@@ -55,6 +55,7 @@ class SplashScreen : Screen() {
 
         val isEdit = isEditMode()
         val scale = remember(isEdit) { Animatable(if (isEdit) 1f else 0f) }
+//        val alpha = remember(isEdit) { Animatable(0.5f) }
         val permissionManager = rememberPermissionManager()
         val composition = rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.splash))
         val progress = animateLottieCompositionAsState(composition.value)
@@ -67,6 +68,11 @@ class SplashScreen : Screen() {
                 .fillMaxSize(),
             contentAlignment = Alignment.Center
         ) {
+//            AnalogTvNoise(
+//                modifier = Modifier
+//                    .fillMaxSize()
+//                    .alpha(alpha.value)
+//            )
             LottieAnimation(
                 modifier = Modifier.padding(120.dp),
                 composition = composition.value,
@@ -97,6 +103,14 @@ class SplashScreen : Screen() {
                         OvershootInterpolator(4f).getInterpolation(it)
                     })
             )
+//            alpha.animateTo(
+//                targetValue = 0f,
+//                animationSpec = tween(
+//                    durationMillis = 18000,
+//                    easing = {
+//                        OvershootInterpolator(4f).getInterpolation(it)
+//                    })
+//            )
             delay(1000L)
             navController.openAsTop<MainScreen>()
         }

+ 2 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/data/github/remote/Asset.kt

@@ -8,9 +8,11 @@
 
 package org.mjdev.tvlib.data.github.remote
 
+import androidx.annotation.Keep
 import com.squareup.moshi.Json
 import com.squareup.moshi.JsonClass
 
+@Keep
 @JsonClass(generateAdapter = true)
 data class Asset(
 

+ 2 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/data/github/remote/Release.kt

@@ -8,9 +8,11 @@
 
 package org.mjdev.tvlib.data.github.remote
 
+import androidx.annotation.Keep
 import com.squareup.moshi.Json
 import com.squareup.moshi.JsonClass
 
+@Keep
 @Suppress("MemberVisibilityCanBePrivate")
 @JsonClass(generateAdapter = true)
 data class Release(

+ 2 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/data/github/remote/User.kt

@@ -8,9 +8,11 @@
 
 package org.mjdev.tvlib.data.github.remote
 
+import androidx.annotation.Keep
 import com.squareup.moshi.Json
 import com.squareup.moshi.JsonClass
 
+@Keep
 @JsonClass(generateAdapter = true)
 data class User(
 

+ 5 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/extensions/ContextExt.kt

@@ -13,12 +13,17 @@ import android.app.UiModeManager
 import android.content.Context
 import android.content.ContextWrapper
 import android.content.res.Configuration
+import android.os.Build
 import android.text.format.DateFormat
 import timber.log.Timber
 import java.util.Date
 
 object ContextExt {
 
+    val Context.isEink: Boolean
+        get() =
+            Build.DEVICE == "Mudita Kompakt"
+
     val Context.isTV: Boolean
         get() = runCatching {
             val uiModeManager = getSystemService(Context.UI_MODE_SERVICE) as UiModeManager

+ 0 - 62
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/DimensionSubcomposeLayout.kt

@@ -1,62 +0,0 @@
-/*
- *  Copyright (c) Milan Jurkulák 2023.
- *  Contact:
- *  e: mimoccc@gmail.com
- *  e: mj@mjdev.org
- *  w: https://mjdev.org
- */
-
-package org.mjdev.tvlib.ui
-
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.layout.Measurable
-import androidx.compose.ui.layout.Placeable
-import androidx.compose.ui.layout.SubcomposeLayout
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.Constraints
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.DpSize
-
-@Composable
-internal fun DimensionSubComposeLayout(
-    modifier: Modifier = Modifier,
-    density: Density = LocalDensity.current,
-    mainContent: @Composable () -> Unit,
-    dependentContent: @Composable (DpSize) -> Unit
-) = SubcomposeLayout(
-    modifier = modifier
-) { constraints: Constraints ->
-    val mainPlaceable = subcompose(
-        SlotsEnum.Main,
-        mainContent
-    ).map { measurable ->
-        measurable.measure(constraints.copy(
-            minWidth = 0,
-            minHeight = 0
-        ))
-    }.first()
-    val dependentPlaceable: Placeable = subcompose(
-        SlotsEnum.Dependent
-    ) {
-        dependentContent(
-            DpSize(
-                density.run { mainPlaceable.width.toDp() },
-                density.run { mainPlaceable.height.toDp() }
-            )
-        )
-    }.map { measurable: Measurable ->
-        measurable.measure(constraints)
-    }.first()
-    layout(
-        mainPlaceable.width,
-        mainPlaceable.height
-    ) {
-        dependentPlaceable.placeRelative(0, 0)
-    }
-}
-
-/**
- * Enum class for SubcomposeLayouts with main and dependent Composables
- */
-enum class SlotsEnum { Main, Dependent }

+ 0 - 53
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/animatePlacement.kt

@@ -1,53 +0,0 @@
-/*
- *  Copyright (c) Milan Jurkulák 2023.
- *  Contact:
- *  e: mimoccc@gmail.com
- *  e: mj@mjdev.org
- *  w: https://mjdev.org
- */
-
-package org.mjdev.tvlib.ui
-
-import androidx.compose.animation.core.Animatable
-import androidx.compose.animation.core.AnimationVector2D
-import androidx.compose.animation.core.Spring.StiffnessMediumLow
-import androidx.compose.animation.core.VectorConverter
-import androidx.compose.animation.core.spring
-import androidx.compose.foundation.layout.offset
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.composed
-import androidx.compose.ui.layout.onPlaced
-import androidx.compose.ui.layout.positionInParent
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.round
-import kotlinx.coroutines.launch
-
-@Suppress("unused")
-fun Modifier.animatePlacement(): Modifier = composed {
-    val scope = rememberCoroutineScope()
-    var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
-    var animatable by remember {
-        mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
-    }
-    onPlaced {
-        // Calculate the position in the parent layout
-        targetOffset = it.positionInParent().round()
-    }.offset {
-        // Animate to the new target offset when alignment changes.
-        val anim = animatable ?: Animatable(targetOffset, IntOffset.VectorConverter)
-            .also { animatable = it }
-        if (anim.targetValue != targetOffset) {
-            scope.launch {
-                anim.animateTo(targetOffset, spring(stiffness = StiffnessMediumLow))
-            }
-        }
-        // Offset the child in the opposite direction to the targetOffset, and slowly catch
-        // up to zero offset via an animation to achieve an overall animated movement.
-        animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
-    }
-}

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/complex/XmlLayout.kt

@@ -45,6 +45,6 @@ fun XmlLayout(
                     }
                 }
             }
-        },
+        }
     )
 }

+ 34 - 11
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/AnalogTvNoise.kt → tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/special/AnalogTvNoise.kt

@@ -5,7 +5,7 @@
  *  e: mj@mjdev.org
  *  w: https://mjdev.org
  */
-package org.mjdev.tvlib.ui
+package org.mjdev.tvlib.ui.components.special
 
 import android.content.Context
 import android.graphics.Bitmap
@@ -13,9 +13,14 @@ import android.graphics.Canvas
 import android.graphics.Color
 import android.util.AttributeSet
 import android.view.View
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.AndroidView
+import org.mjdev.tvlib.annotations.Previews
 import java.util.Random
 import java.util.Timer
 import java.util.TimerTask
+import kotlin.math.max
 
 class AnalogTvNoise @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
@@ -23,22 +28,22 @@ class AnalogTvNoise @JvmOverloads constructor(
     private val mRandom = Random(System.currentTimeMillis())
     private var mTileWidth = 0
     private var mTileHeight = 0
-    private var mScalledBitmap: Bitmap? = null
+    private var mScaledBitmap: Bitmap? = null
     private var mBitmap: Bitmap? = null
     private var mPixels: IntArray? = null
     private var mTimer: Timer? = null
 
     override fun onDraw(canvas: Canvas) {
-        if (mScalledBitmap == null) return
-        for (i in 0 until DIVIDER_WIDTH_SCALLED) {
-            canvas.drawBitmap(mScalledBitmap!!, (i * mScalledBitmap!!.width).toFloat(), 0f, null)
+        if (mScaledBitmap == null) return
+        for (i in 0 until DIVIDER_WIDTH_SCALED) {
+            canvas.drawBitmap(mScaledBitmap!!, (i * mScaledBitmap!!.width).toFloat(), 0f, null)
         }
     }
 
     override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
         super.onLayout(changed, left, top, right, bottom)
-        val tileWidth = width / DIVIDER_WIDTH
-        val tileHeight = height / DIVIDER_HEIGHT
+        val tileWidth = max(1, width / DIVIDER_WIDTH)
+        val tileHeight = max(1, height / DIVIDER_HEIGHT)
         if (mTileWidth != tileWidth || mTileHeight != tileHeight || mPixels == null) {
             mPixels = IntArray(tileWidth * tileHeight)
             mBitmap = Bitmap.createBitmap(tileWidth, tileHeight, Bitmap.Config.RGB_565)
@@ -85,19 +90,37 @@ class AnalogTvNoise @JvmOverloads constructor(
     private fun generateNoise() {
         if (mPixels == null || mBitmap == null) return
         for (i in 0 until mTileWidth * mTileHeight) {
-            val pix = Math.max(40, mRandom.nextInt(255))
+            val pix = max(40, mRandom.nextInt(255))
             mPixels!![i] = Color.rgb(pix, pix, pix)
         }
-        val width = width / DIVIDER_WIDTH_SCALLED
+        val width = width / DIVIDER_WIDTH_SCALED
         mBitmap?.setPixels(mPixels!!, 0, mTileWidth, 0, 0, mTileWidth, mTileHeight)
-        mScalledBitmap = Bitmap.createScaledBitmap(mBitmap!!, width, height, false)
+        mScaledBitmap = Bitmap.createScaledBitmap(
+            mBitmap!!,
+            max(1, width),
+            max(1, height),
+            false
+        )
     }
 
     companion object {
         private const val DIVIDER_WIDTH = 8
         private const val DIVIDER_HEIGHT = 4
-        private const val DIVIDER_WIDTH_SCALLED = 2
+        private const val DIVIDER_WIDTH_SCALED = 2
         private const val ANIM_INTERVAL = 50
     }
 
+}
+
+@Previews
+@Composable
+fun AnalogTvNoise(
+    modifier: Modifier = Modifier
+) {
+    AndroidView(
+        modifier = modifier,
+        factory = { context ->
+            AnalogTvNoise(context)
+        }
+    )
 }

+ 62 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/special/DimensionSubcomposeLayout.kt

@@ -0,0 +1,62 @@
+package org.mjdev.tvlib.ui.components.special///*
+// *  Copyright (c) Milan Jurkulák 2023.
+// *  Contact:
+// *  e: mimoccc@gmail.com
+// *  e: mj@mjdev.org
+// *  w: https://mjdev.org
+// */
+//
+//package org.mjdev.tvlib.ui
+//
+//import androidx.compose.runtime.Composable
+//import androidx.compose.ui.Modifier
+//import androidx.compose.ui.layout.Measurable
+//import androidx.compose.ui.layout.Placeable
+//import androidx.compose.ui.layout.SubcomposeLayout
+//import androidx.compose.ui.platform.LocalDensity
+//import androidx.compose.ui.unit.Constraints
+//import androidx.compose.ui.unit.Density
+//import androidx.compose.ui.unit.DpSize
+//
+//@Composable
+//internal fun DimensionSubComposeLayout(
+//    modifier: Modifier = Modifier,
+//    density: Density = LocalDensity.current,
+//    mainContent: @Composable () -> Unit,
+//    dependentContent: @Composable (DpSize) -> Unit
+//) = SubcomposeLayout(
+//    modifier = modifier
+//) { constraints: Constraints ->
+//    val mainPlaceable = subcompose(
+//        SlotsEnum.Main,
+//        mainContent
+//    ).map { measurable ->
+//        measurable.measure(constraints.copy(
+//            minWidth = 0,
+//            minHeight = 0
+//        ))
+//    }.first()
+//    val dependentPlaceable: Placeable = subcompose(
+//        SlotsEnum.Dependent
+//    ) {
+//        dependentContent(
+//            DpSize(
+//                density.run { mainPlaceable.width.toDp() },
+//                density.run { mainPlaceable.height.toDp() }
+//            )
+//        )
+//    }.map { measurable: Measurable ->
+//        measurable.measure(constraints)
+//    }.first()
+//    layout(
+//        mainPlaceable.width,
+//        mainPlaceable.height
+//    ) {
+//        dependentPlaceable.placeRelative(0, 0)
+//    }
+//}
+//
+///**
+// * Enum class for SubcomposeLayouts with main and dependent Composables
+// */
+//enum class SlotsEnum { Main, Dependent }

+ 53 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/ui/components/special/animatePlacement.kt

@@ -0,0 +1,53 @@
+package org.mjdev.tvlib.ui.components.special///*
+// *  Copyright (c) Milan Jurkulák 2023.
+// *  Contact:
+// *  e: mimoccc@gmail.com
+// *  e: mj@mjdev.org
+// *  w: https://mjdev.org
+// */
+//
+//package org.mjdev.tvlib.ui
+//
+//import androidx.compose.animation.core.Animatable
+//import androidx.compose.animation.core.AnimationVector2D
+//import androidx.compose.animation.core.Spring.StiffnessMediumLow
+//import androidx.compose.animation.core.VectorConverter
+//import androidx.compose.animation.core.spring
+//import androidx.compose.foundation.layout.offset
+//import androidx.compose.runtime.getValue
+//import androidx.compose.runtime.mutableStateOf
+//import androidx.compose.runtime.remember
+//import androidx.compose.runtime.rememberCoroutineScope
+//import androidx.compose.runtime.setValue
+//import androidx.compose.ui.Modifier
+//import androidx.compose.ui.composed
+//import androidx.compose.ui.layout.onPlaced
+//import androidx.compose.ui.layout.positionInParent
+//import androidx.compose.ui.unit.IntOffset
+//import androidx.compose.ui.unit.round
+//import kotlinx.coroutines.launch
+//
+//@Suppress("unused")
+//fun Modifier.animatePlacement(): Modifier = composed {
+//    val scope = rememberCoroutineScope()
+//    var targetOffset by remember { mutableStateOf(IntOffset.Zero) }
+//    var animatable by remember {
+//        mutableStateOf<Animatable<IntOffset, AnimationVector2D>?>(null)
+//    }
+//    onPlaced {
+//        // Calculate the position in the parent layout
+//        targetOffset = it.positionInParent().round()
+//    }.offset {
+//        // Animate to the new target offset when alignment changes.
+//        val anim = animatable ?: Animatable(targetOffset, IntOffset.VectorConverter)
+//            .also { animatable = it }
+//        if (anim.targetValue != targetOffset) {
+//            scope.launch {
+//                anim.animateTo(targetOffset, spring(stiffness = StiffnessMediumLow))
+//            }
+//        }
+//        // Offset the child in the opposite direction to the targetOffset, and slowly catch
+//        // up to zero offset via an animation to achieve an overall animated movement.
+//        animatable?.let { it.value - targetOffset } ?: IntOffset.Zero
+//    }
+//}

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

@@ -48,6 +48,5 @@ fun AppUpdateAvailableMessage(
     error = message.asException(),
     backgroundColor = backgroundColor,
     dismissible = true,
-    dismissState = dismissState,
     dismissOnClick = onButtonClick
 )

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

@@ -42,10 +42,10 @@ fun AppsRow(
     startApp: Context.(app: App?) -> Unit = { app ->
         startActivity(app?.intent)
     },
-    apps: State<List<App>> = rememberAppsManager().collectAsState(emptyList())
+    apps: State<List<App>> = rememberAppsManager().collectAsState(emptyList()),
+    cardWidth: Dp = computeCardWidth(3f)
 ) {
     val context: Context = LocalContext.current
-    val cardWidth = computeCardWidth(3f)
     if (apps.value.isNotEmpty()) {
         CategoryRow(
             title = title,

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

@@ -63,12 +63,12 @@ fun ErrorMessage(
     backgroundShape: Shape = RoundedCornerShape(roundSize),
     dismissible: Boolean = true,
     visible: Boolean = isEditMode(),
-    dismissState: MutableState<Boolean> = mutableStateOf(!visible),
+    visibleState: MutableState<Boolean> = mutableStateOf(visible),
     enter: EnterTransition = EnterTransition.None,
     exit: ExitTransition = ExitTransition.None,
     dismissOnClick: () -> Unit = {},
 ) = AnimatedVisibility(
-    visible = !dismissState.value,
+    visible = visibleState.value,
     enter = enter,
     exit = exit
 ) {
@@ -114,7 +114,7 @@ fun ErrorMessage(
                     contentPadding = PaddingValues(8.dp, 0.dp),
                     containerColor = Color.Black.copy(alpha = 0.2f),
                     onClick = {
-                        dismissState.value = true
+                        visibleState.value = false
                         dismissOnClick.invoke()
                     }
                 )

+ 4 - 6
tvlib/src/main/kotlin/org/mjdev/tvlib/updater/AppUpdater.kt

@@ -23,7 +23,7 @@ import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.collectLatest
-import kotlinx.coroutines.flow.firstOrNull
+import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.launch
@@ -75,16 +75,14 @@ class AppUpdater(
     }
 
     val isUpdateAvailable: Flow<Boolean> = serverTimestamp.map { st ->
-        val lt = installedTimestamp.firstOrNull() ?: 0L
-        st > lt
+        val lt = installedTimestamp.first()
+        if (st > 0) (st > lt) else false
     }
 
     private fun storeTimestamp(timestamp: Long) {
         prefs.edit().apply {
             putLong(keyName, timestamp)
-            apply()
-            commit()
-        }
+        }.apply()
     }
 
     @MainThread