Просмотр исходного кода

design improvements

design improvements

design improvements
Milan Jurkulak 3 лет назад
Родитель
Сommit
28815fedb6

+ 3 - 0
app/src/main/AndroidManifest.xml

@@ -62,6 +62,7 @@
             android:clearTaskOnLaunch="true"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="true"
+            android:theme="@style/Theme.TvApp"
             android:finishOnTaskLaunch="true"
             android:launchMode="singleTask">
 
@@ -94,6 +95,7 @@
             android:clearTaskOnLaunch="true"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="true"
+            android:theme="@style/Theme.TvApp"
             android:finishOnTaskLaunch="true"
             android:label="@string/title_iptv"
             android:launchMode="singleTask">
@@ -117,6 +119,7 @@
             android:clearTaskOnLaunch="true"
             android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
             android:exported="true"
+            android:theme="@style/Theme.TvApp"
             android:finishOnTaskLaunch="true"
             android:label="@string/title_web"
             android:launchMode="singleTask">

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

@@ -51,7 +51,7 @@ class MainPage : Page() {
     @Composable
     override fun Content() {
         val viewModel: MainViewModel = appViewModel { context ->
-            MainViewModel.mockMainViewModel(context)
+            MainViewModel.mock(context)
         }
 
         val streamingData = viewModel.movieList.collectAsState()

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/ui/screens/DetailScreen.kt

@@ -50,7 +50,7 @@ class DetailScreen : Screen() {
     override fun ComposeScreen() {
 
         val viewModel: DetailViewModel = appViewModel { context ->
-            DetailViewModel.mockDetailViewModel(context)
+            DetailViewModel.mock(context)
         }
 
         val data: Any? = remember { args[data] }

+ 3 - 3
app/src/main/kotlin/org/mjdev/tvapp/ui/screens/IPTVScreen.kt

@@ -21,7 +21,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.media3.common.MediaItem
 import androidx.navigation.navArgument
 import org.mjdev.tvapp.R
-import org.mjdev.tvapp.viewmodel.DetailViewModel
+import org.mjdev.tvapp.viewmodel.IPTVViewModel
 import org.mjdev.tvlib.annotations.TvPreview
 import org.mjdev.tvlib.extensions.HiltExt.appViewModel
 import org.mjdev.tvlib.navigation.AnyType
@@ -52,8 +52,8 @@ class IPTVScreen : Screen() {
     @Composable
     override fun ComposeScreen() {
 
-        val viewModel: DetailViewModel = appViewModel { context ->
-            DetailViewModel.mockDetailViewModel(context)
+        val viewModel: IPTVViewModel = appViewModel { context ->
+            IPTVViewModel.mock(context)
         }
 
         val data: Any? by lazy {

+ 6 - 8
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/DetailViewModel.kt

@@ -11,7 +11,6 @@
 package org.mjdev.tvapp.viewmodel
 
 import android.content.Context
-import androidx.media3.common.MediaItem
 import dagger.hilt.android.lifecycle.HiltViewModel
 import org.mjdev.tvapp.data.local.Movie
 import org.mjdev.tvlib.helpers.cursor.AudioCursor
@@ -49,12 +48,11 @@ class DetailViewModel @Inject constructor() : BaseViewModel() {
 
     val mediaItems: List<Any> get() = dao.movieDao.all
 
-    val cache = mutableMapOf<KClass<*>, List<MediaItem>>()
+    val cache = mutableMapOf<KClass<*>, List<*>>()
 
-    // todo this should be improved
     fun mediaItemsFor(
         data: Any?
-    ): List<MediaItem> = when (data) {
+    ): List<Any?> = when (data) {
         is ItemAudio -> getCachedList<ItemAudio> { localAudioCursor }
         is ItemVideo -> getCachedList<ItemVideo> { localVideoCursor }
         is ItemPhoto -> getCachedList<ItemPhoto> { localPhotoCursor }
@@ -62,19 +60,19 @@ class DetailViewModel @Inject constructor() : BaseViewModel() {
         else -> listOf(data.mediaItem)
     }
 
-    private inline fun <reified T> getCachedList(creator: () -> List<*>): List<MediaItem> {
+    private inline fun <reified T> getCachedList(creator: () -> List<*>): List<*> {
         if (!cache.containsKey(T::class)) {
             creator().let { list ->
-                cache[T::class] = list.map { item -> item.mediaItem }
+                cache[T::class] = list
             }
         }
-        return cache[T::class] ?: emptyList()
+        return cache[T::class] ?: emptyList<Any>()
     }
 
     companion object {
 
         @Suppress("unused")
-        fun mockDetailViewModel(
+        fun mock(
             context: Context
         ): DetailViewModel = DetailViewModel().apply {
             dao = DAO(context)

+ 88 - 0
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/IPTVViewModel.kt

@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) Milan Jurkulák 2023.
+ * Contact:
+ * e: mimoccc@gmail.com
+ * e: mj@mjdev.org
+ * w: https://mjdev.org
+ */
+
+@file:Suppress("unused")
+
+package org.mjdev.tvapp.viewmodel
+
+import android.content.Context
+import androidx.media3.common.MediaItem
+import dagger.hilt.android.lifecycle.HiltViewModel
+import org.mjdev.tvapp.data.local.Movie
+import org.mjdev.tvlib.helpers.cursor.AudioCursor
+import org.mjdev.tvlib.helpers.cursor.PhotoCursor
+import org.mjdev.tvlib.helpers.cursor.VideoCursor
+import org.mjdev.tvlib.network.NetworkConnectivityService
+import org.mjdev.tvlib.viewmodel.BaseViewModel
+import org.mjdev.tvapp.database.DAO
+import org.mjdev.tvlib.extensions.MediaItemExt.mediaItem
+import org.mjdev.tvlib.interfaces.ItemAudio
+import org.mjdev.tvlib.interfaces.ItemPhoto
+import org.mjdev.tvlib.interfaces.ItemVideo
+import org.mjdev.tvlib.network.NetworkConnectivityServiceImpl
+import javax.inject.Inject
+import kotlin.reflect.KClass
+
+@Suppress("MemberVisibilityCanBePrivate")
+@HiltViewModel
+class IPTVViewModel @Inject constructor() : BaseViewModel() {
+
+    @Inject
+    lateinit var dao: DAO
+
+    @Inject
+    lateinit var networkInfo: NetworkConnectivityService
+
+    @Inject
+    lateinit var localAudioCursor: AudioCursor
+
+    @Inject
+    lateinit var localVideoCursor: VideoCursor
+
+    @Inject
+    lateinit var localPhotoCursor: PhotoCursor
+
+    val mediaItems: List<Any> get() = dao.movieDao.all
+
+    val cache = mutableMapOf<KClass<*>, List<MediaItem>>()
+
+    fun mediaItemsFor(
+        data: Any?
+    ): List<MediaItem> = when (data) {
+        is ItemAudio -> getCachedList<ItemAudio> { localAudioCursor }
+        is ItemVideo -> getCachedList<ItemVideo> { localVideoCursor }
+        is ItemPhoto -> getCachedList<ItemPhoto> { localPhotoCursor }
+        is Movie -> getCachedList<Movie> { mediaItems }
+        else -> listOf(data.mediaItem)
+    }
+
+    private inline fun <reified T> getCachedList(creator: () -> List<*>): List<MediaItem> {
+        if (!cache.containsKey(T::class)) {
+            creator().let { list ->
+                cache[T::class] = list.map { item -> item.mediaItem }
+            }
+        }
+        return cache[T::class] ?: emptyList()
+    }
+
+    companion object {
+
+        @Suppress("unused")
+        fun mock(
+            context: Context
+        ): IPTVViewModel = IPTVViewModel().apply {
+            dao = DAO(context)
+            networkInfo = NetworkConnectivityServiceImpl(context)
+            localAudioCursor = AudioCursor(context)
+            localVideoCursor = VideoCursor(context)
+            localPhotoCursor = PhotoCursor(context)
+        }
+
+    }
+
+}

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

@@ -122,7 +122,7 @@ class MainViewModel @Inject constructor(
     companion object {
 
         @Suppress("unused")
-        fun mockMainViewModel(
+        fun mock(
             context: Context
         ): MainViewModel = MainViewModel(context).apply {
             dao = DAO(context)

+ 34 - 14
app/src/main/kotlin/org/mjdev/tvapp/widget/MainAppWidget.kt

@@ -10,18 +10,23 @@ package org.mjdev.tvapp.widget
 
 import android.content.Context
 import androidx.compose.runtime.Composable
-import androidx.compose.ui.tooling.preview.Preview
 import androidx.glance.Button
 import androidx.glance.GlanceComposable
 import androidx.glance.GlanceId
 import androidx.glance.GlanceModifier
+import androidx.glance.Image
+import androidx.glance.ImageProvider
 import androidx.glance.action.actionStartActivity
 import androidx.glance.action.clickable
 import androidx.glance.appwidget.GlanceAppWidget
 import androidx.glance.appwidget.action.actionRunCallback
 import androidx.glance.appwidget.provideContent
+import androidx.glance.layout.Box
 import androidx.glance.layout.Column
+import androidx.glance.layout.fillMaxSize
+import androidx.glance.layout.fillMaxWidth
 import androidx.glance.text.Text
+import org.mjdev.tvapp.R
 import org.mjdev.tvapp.activity.MainActivity
 
 class MainAppWidget : GlanceAppWidget() {
@@ -31,24 +36,39 @@ class MainAppWidget : GlanceAppWidget() {
         }
     }
 
-    @Preview
     @GlanceComposable
     @Composable
     fun WidgetContent() {
-        Column {
-            Text(
-                "Hello World",
-                modifier = GlanceModifier.clickable {
-                    actionStartActivity<MainActivity>()
-                }
-
+        Box(
+            modifier = GlanceModifier.fillMaxSize()
+        ) {
+            Image(
+                modifier = GlanceModifier.fillMaxWidth(),
+                provider = ImageProvider(R.drawable.audio_player_default_show_bg) ,
+                contentDescription = ""
             )
-            Button(
-                text = "PlayPause",
-                onClick = {
-                    actionRunCallback<PlayPauseAction>()
-                }
+            Image(
+                modifier = GlanceModifier.fillMaxSize(),
+                provider = ImageProvider(R.drawable.bgcase) ,
+                contentDescription = ""
             )
+            Column(
+                modifier = GlanceModifier.fillMaxSize()
+            ) {
+                Text(
+                    "Hello World",
+                    modifier = GlanceModifier.clickable {
+                        actionStartActivity<MainActivity>()
+                    }
+
+                )
+                Button(
+                    text = "PlayPause",
+                    onClick = {
+                        actionRunCallback<PlayPauseAction>()
+                    }
+                )
+            }
         }
     }
 }

+ 11 - 3
app/src/main/res/values/themes.xml

@@ -8,16 +8,24 @@
  */
 -->
 
-<resources>
+<resources xmlns:tools="http://schemas.android.com/tools">
 
     <style name="Theme.TvApp" parent="android:Theme.Material.Light.NoActionBar.TranslucentDecor">
-
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowBackground">#FF444444</item>
-        <item name="android:navigationBarColor">#FF444444</item>
+        <item name="android:navigationBarColor">#00000000</item>
+        <item name="statusBarBackground">#00000000</item>
+        <item name="android:statusBarColor">#00000000</item>
         <item name="android:colorBackground">#FF444444</item>
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:windowIsTranslucent">true</item>
         <item name="android:windowTranslucentNavigation">true</item>
+        <item name="android:windowFullscreen">false</item>
+        <item name="android:windowLayoutInDisplayCutoutMode" tools:ignore="NewApi">always</item>
+    </style>
 
+    <style name="Theme.TvApp.Fullscreen" parent="Theme.TvApp">
+        <item name="android:windowFullscreen">true</item>
     </style>
 
 </resources>

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

@@ -13,8 +13,6 @@ package org.mjdev.tvlib.ui.components.media
 import android.annotation.SuppressLint
 import androidx.compose.foundation.layout.Box
 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.DisposableEffect
 import androidx.compose.ui.Modifier
@@ -40,8 +38,6 @@ fun MediaPlayerContainer(
         PlayerControlView(
             modifier = modifier
                 .recomposeHighlighter()
-                .navigationBarsPadding()
-                .statusBarsPadding()
                 .fillMaxSize(),
             state = state
         )

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

@@ -18,7 +18,7 @@ import androidx.tv.material3.DrawerValue
 import androidx.tv.material3.ExperimentalTvMaterial3Api
 import androidx.tv.material3.rememberDrawerState
 import org.mjdev.tvlib.annotations.TvPreview
-import org.mjdev.tvlib.extensions.ComposeExt
+import org.mjdev.tvlib.extensions.ComposeExt.isEditMode
 
 @OptIn(ExperimentalTvMaterial3Api::class)
 @TvPreview
@@ -26,7 +26,8 @@ import org.mjdev.tvlib.extensions.ComposeExt
 fun SettingsDrawer(
     modifier: Modifier = Modifier,
     drawerState: DrawerState = rememberDrawerState(
-        if (ComposeExt.isEditMode()) DrawerValue.Open else DrawerValue.Closed
+        if (isEditMode()) DrawerValue.Open
+        else DrawerValue.Closed
     ),
     onTouchOutside: () -> Unit = {},
     content: @Composable () -> Unit = {

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

@@ -26,6 +26,7 @@ import org.mjdev.tvlib.extensions.ModifierExt.recomposeHighlighter
 @Preview
 @Composable
 fun SettingsDrawerContent(
+    modifier: Modifier = Modifier
 ) {
     Column(
         modifier = Modifier