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

code clean / icons for screens

Milan Jurkulak 3 лет назад
Родитель
Сommit
dc9f717c24
100 измененных файлов с 441 добавлено и 241 удалено
  1. 75 0
      .github/workflows/build-gradle-project.yml
  2. 33 0
      .gitignore
  3. BIN
      .gradle/8.0/checksums/checksums.lock
  4. BIN
      .gradle/8.0/checksums/md5-checksums.bin
  5. BIN
      .gradle/8.0/checksums/sha1-checksums.bin
  6. BIN
      .gradle/8.0/dependencies-accessors/dependencies-accessors.lock
  7. 0 0
      .gradle/8.0/dependencies-accessors/gc.properties
  8. BIN
      .gradle/8.0/executionHistory/executionHistory.bin
  9. BIN
      .gradle/8.0/executionHistory/executionHistory.lock
  10. BIN
      .gradle/8.0/fileChanges/last-build.bin
  11. BIN
      .gradle/8.0/fileHashes/fileHashes.bin
  12. BIN
      .gradle/8.0/fileHashes/fileHashes.lock
  13. BIN
      .gradle/8.0/fileHashes/resourceHashesCache.bin
  14. 0 0
      .gradle/8.0/gc.properties
  15. BIN
      .gradle/buildOutputCleanup/buildOutputCleanup.lock
  16. 2 0
      .gradle/buildOutputCleanup/cache.properties
  17. BIN
      .gradle/buildOutputCleanup/outputFiles.bin
  18. BIN
      .gradle/file-system.probe
  19. 0 0
      .gradle/vcs-1/gc.properties
  20. 3 0
      .idea/.gitignore
  21. 1 0
      .idea/.name
  22. 6 0
      .idea/compiler.xml
  23. 19 0
      .idea/gradle.xml
  24. 6 0
      .idea/kotlinc.xml
  25. 10 0
      .idea/misc.xml
  26. 6 0
      .idea/vcs.xml
  27. 2 2
      app/build.gradle.kts
  28. 2 0
      app/src/main/kotlin/org/mjdev/tvapp/activity/MainActivity.kt
  29. 11 11
      app/src/main/kotlin/org/mjdev/tvapp/api/MovieAPI.kt
  30. 0 25
      app/src/main/kotlin/org/mjdev/tvapp/base/helpers/Option.kt
  31. 25 0
      app/src/main/kotlin/org/mjdev/tvapp/base/helpers/Result.kt
  32. 1 0
      app/src/main/kotlin/org/mjdev/tvapp/base/helpers/StateContextWrapper.kt
  33. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/base/navigation/Screen.kt
  34. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/base/network/ConnectivityCallback.kt
  35. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/base/network/NetworkConnectivityServiceImpl.kt
  36. 83 83
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/complex/ListWithPreview.kt
  37. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/complex/ScreenView.kt
  38. 0 1
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/complex/Title.kt
  39. 12 1
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/image/ImageAny.kt
  40. 0 3
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/navigation/Navigation.kt
  41. 0 2
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/navigation/NavigationRow.kt
  42. 3 2
      app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/text/CircleText.kt
  43. 3 3
      app/src/main/kotlin/org/mjdev/tvapp/repository/MovieRepository.kt
  44. 97 95
      app/src/main/kotlin/org/mjdev/tvapp/ui/components/MyComposeView.kt
  45. 2 2
      app/src/main/kotlin/org/mjdev/tvapp/ui/screens/DetailScreen.kt
  46. 3 5
      app/src/main/kotlin/org/mjdev/tvapp/ui/screens/PlayerScreen.kt
  47. 29 0
      app/src/main/kotlin/org/mjdev/tvapp/ui/screens/SplashScreen.kt
  48. 2 2
      app/src/main/kotlin/org/mjdev/tvapp/ui/screens/SubscriptionScreen.kt
  49. BIN
      buildSrc/.gradle/8.0/executionHistory/executionHistory.bin
  50. BIN
      buildSrc/.gradle/8.0/executionHistory/executionHistory.lock
  51. BIN
      buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock
  52. BIN
      buildSrc/.gradle/file-system.probe
  53. BIN
      buildSrc/build/classes/kotlin/main/META-INF/buildSrc.kotlin_module
  54. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/extensions/DependencyHandlerKt.class
  55. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/helper/CustomEventLogger.class
  56. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$Companion.class
  57. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$1.class
  58. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$3.class
  59. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$4.class
  60. BIN
      buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin.class
  61. 1 0
      buildSrc/build/kotlin/buildSrcjar-classes.txt
  62. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab
  63. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream
  64. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len
  65. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len
  66. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at
  67. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i
  68. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len
  69. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab
  70. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream
  71. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len
  72. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len
  73. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at
  74. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i
  75. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len
  76. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab
  77. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream
  78. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len
  79. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len
  80. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at
  81. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i
  82. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len
  83. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab
  84. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream
  85. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len
  86. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len
  87. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at
  88. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i
  89. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len
  90. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab
  91. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.keystream
  92. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.keystream.len
  93. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.len
  94. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.values.at
  95. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab_i
  96. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab_i.len
  97. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab
  98. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream
  99. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len
  100. BIN
      buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len

+ 75 - 0
.github/workflows/build-gradle-project.yml

@@ -0,0 +1,75 @@
+name: Build Gradle project
+# on settings
+on:
+  push:
+    branches:
+      - main
+# jobs
+jobs:
+  build-gradle-project:
+    runs-on: ubuntu-latest
+#permissions
+    permissions:
+      contents: write
+      deployments: write
+      pages: write
+# job steps
+    steps:
+      - name: Checkout project sources
+        id: checkout_project
+        uses: actions/checkout@v3
+# setup jdk 17
+      - name: Set up JDK 17
+        id: setup_java
+        uses: actions/setup-java@v3
+        with:
+          java-version: '17'
+          distribution: 'temurin'
+          cache: gradle
+# setup gradle
+      - name: Setup Gradle
+        id: setup_gradle
+        uses: gradle/gradle-build-action@v2
+# be sure it is executable
+      - name: Grant execute permission for gradlew
+        id: grant_gradle
+        run: chmod +x gradlew
+# generate version number to env
+      - name: Prepare Version Number
+        id: prepare_version
+        run: |
+          export GRADLE_PATH="./config/version.properties";
+          export GRADLE_FIELD_VMAJ="majorVersion"
+          export GRADLE_FIELD_VMIN="minorVersion"
+          export GRADLE_FIELD_VPAT="patchVersion"
+          export VERSION_VMAJ_TMP=$(grep $GRADLE_FIELD_VMAJ $GRADLE_PATH | cat $2)
+          export VERSION_VMIN_TMP=$(grep $GRADLE_FIELD_VMIN $GRADLE_PATH | cat $2)
+          export VERSION_VMPAT_TMP=$(grep $GRADLE_FIELD_VPAT $GRADLE_PATH | cat $2)
+          export VERSION_MAJOR=$(echo $VERSION_VMAJ_TMP | sed -e 's/^majorVersion=//'  -e 's/"$//')
+          export VERSION_MINOR=$(echo $VERSION_VMIN_TMP | sed -e 's/^minorVersion=//'  -e 's/"$//')
+          export VERSION_PATCH=$(echo $VERSION_VMPAT_TMP | sed -e 's/^patchVersion=//'  -e 's/"$//')
+          export APP_VERSION="$VERSION_MAJOR.$VERSION_MINOR.$VERSION_PATCH"
+          echo "Release Version : $APP_VERSION"
+          echo "GITHUB_APP_VERSION_NAME=$(echo $APP_VERSION)" >> $GITHUB_ENV
+# build apk for release
+      - name: Build Release APK
+        id: build_release_apk
+        run: ./gradlew assembleRelease
+# publish github release
+      - name: Create Release
+        id: release
+        uses: ncipollo/release-action@v1
+        with:
+          name: Release v ${{ env.GITHUB_APP_VERSION_NAME }}
+          allowUpdates: true
+          token: ${{ secrets.TOKEN }}
+          tag: release-${{ env.GITHUB_APP_VERSION_NAME }}
+          artifacts: './app/build/outputs/apk/release/app-release.apk, ./release-notes.txt'
+# update wiki pages
+      - name: Update wiki pages
+        id: update_wiki_pages
+        uses: OrlovM/Wiki-Action@v1
+        with:
+          path: 'wiki'
+          token: ${{ secrets.TOKEN }}
+# done

+ 33 - 0
.gitignore

@@ -0,0 +1,33 @@
+# Gradle files
+.gradle/
+build/
+
+# Local configuration file (sdk path, etc)
+local.properties
+
+# Log/OS Files
+*.log
+
+# Android Studio generated files and folders
+captures/
+.externalNativeBuild/
+.cxx/
+*.apk
+output.json
+
+# IntelliJ
+*.iml
+.idea/
+misc.xml
+deploymentTargetDropDown.xml
+render.experimental.xml
+
+# Keystore files
+*.jks
+*.keystore
+
+# Google Services (e.g. APIs or Firebase)
+google-services.json
+
+# Android Profiling
+*.hprof

BIN
.gradle/8.0/checksums/checksums.lock


BIN
.gradle/8.0/checksums/md5-checksums.bin


BIN
.gradle/8.0/checksums/sha1-checksums.bin


BIN
.gradle/8.0/dependencies-accessors/dependencies-accessors.lock


+ 0 - 0
.gradle/8.0/dependencies-accessors/gc.properties


BIN
.gradle/8.0/executionHistory/executionHistory.bin


BIN
.gradle/8.0/executionHistory/executionHistory.lock


BIN
.gradle/8.0/fileChanges/last-build.bin


BIN
.gradle/8.0/fileHashes/fileHashes.bin


BIN
.gradle/8.0/fileHashes/fileHashes.lock


BIN
.gradle/8.0/fileHashes/resourceHashesCache.bin


+ 0 - 0
.gradle/8.0/gc.properties


BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock


+ 2 - 0
.gradle/buildOutputCleanup/cache.properties

@@ -0,0 +1,2 @@
+#Sun Jun 25 22:54:27 CEST 2023
+gradle.version=8.0

BIN
.gradle/buildOutputCleanup/outputFiles.bin


BIN
.gradle/file-system.probe


+ 0 - 0
.gradle/vcs-1/gc.properties


+ 3 - 0
.idea/.gitignore

@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml

+ 1 - 0
.idea/.name

@@ -0,0 +1 @@
+TvApp

+ 6 - 0
.idea/compiler.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <bytecodeTargetLevel target="17" />
+  </component>
+</project>

+ 19 - 0
.idea/gradle.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="GradleSettings">
+    <option name="linkedExternalProjectsSettings">
+      <GradleProjectSettings>
+        <option name="testRunner" value="GRADLE" />
+        <option name="distributionType" value="DEFAULT_WRAPPED" />
+        <option name="externalProjectPath" value="$PROJECT_DIR$" />
+        <option name="modules">
+          <set>
+            <option value="$PROJECT_DIR$" />
+            <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/buildSrc" />
+          </set>
+        </option>
+      </GradleProjectSettings>
+    </option>
+  </component>
+</project>

+ 6 - 0
.idea/kotlinc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="KotlinJpsPluginSettings">
+    <option name="version" value="1.8.10" />
+  </component>
+</project>

+ 10 - 0
.idea/misc.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/build/classes" />
+  </component>
+  <component name="ProjectType">
+    <option name="id" value="Android" />
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>

+ 2 - 2
app/build.gradle.kts

@@ -50,7 +50,7 @@ android {
     }
     }
 
 
     defaultConfig {
     defaultConfig {
-        applicationId = "org.mjdev.tvapp.tvcomposeintroduction"
+        applicationId = "org.mjdev.tvapp"
 
 
         minSdk = 21
         minSdk = 21
         targetSdk = 33
         targetSdk = 33
@@ -127,7 +127,7 @@ dependencies {
     implementation(kotlin("reflect", "1.8.21"))
     implementation(kotlin("reflect", "1.8.21"))
     // compose base libs
     // compose base libs
     implementation(
     implementation(
-        platform("androidx.compose:compose-bom:2023.06.00")
+        platform("androidx.compose:compose-bom:2023.06.01")
     )
     )
     implementation("androidx.compose.ui:ui-tooling")
     implementation("androidx.compose.ui:ui-tooling")
     implementation("androidx.activity:activity-compose:1.7.2")
     implementation("androidx.activity:activity-compose:1.7.2")

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

@@ -15,11 +15,13 @@ import org.mjdev.tvapp.ui.screens.AboutScreen
 import org.mjdev.tvapp.ui.screens.DetailScreen
 import org.mjdev.tvapp.ui.screens.DetailScreen
 import org.mjdev.tvapp.ui.screens.MainScreen
 import org.mjdev.tvapp.ui.screens.MainScreen
 import org.mjdev.tvapp.ui.screens.PlayerScreen
 import org.mjdev.tvapp.ui.screens.PlayerScreen
+import org.mjdev.tvapp.ui.screens.SplashScreen
 import org.mjdev.tvapp.ui.screens.SubscriptionScreen
 import org.mjdev.tvapp.ui.screens.SubscriptionScreen
 
 
 @AndroidEntryPoint
 @AndroidEntryPoint
 class MainActivity : ComposableActivity ({
 class MainActivity : ComposableActivity ({
 
 
+    screen(route = SplashScreen()) // todo start screen
     screen(route = MainScreen(), isHomeScreen = true)
     screen(route = MainScreen(), isHomeScreen = true)
     screen(route = DetailScreen())
     screen(route = DetailScreen())
     screen(route = PlayerScreen())
     screen(route = PlayerScreen())

+ 11 - 11
app/src/main/kotlin/org/mjdev/tvapp/api/MovieAPI.kt

@@ -8,8 +8,8 @@
 
 
 package org.mjdev.tvapp.api
 package org.mjdev.tvapp.api
 
 
-import org.mjdev.tvapp.base.helpers.Option
-import org.mjdev.tvapp.base.helpers.Option.Companion.unwrapOr
+import org.mjdev.tvapp.base.helpers.Result
+import org.mjdev.tvapp.base.helpers.Result.Companion.unwrapOr
 import org.mjdev.tvapp.data.Category
 import org.mjdev.tvapp.data.Category
 import org.mjdev.tvapp.data.Movie
 import org.mjdev.tvapp.data.Movie
 import org.mjdev.tvapp.mock.MovieList
 import org.mjdev.tvapp.mock.MovieList
@@ -17,8 +17,8 @@ import org.mjdev.tvapp.mock.MovieList
 @Suppress("RedundantSuspendModifier")
 @Suppress("RedundantSuspendModifier")
 class MovieAPI {
 class MovieAPI {
 
 
-    suspend fun loadCategoryList(): Option<List<Category>> {
-        return Option.Some(MovieList.categories.map { name ->
+    suspend fun loadCategoryList(): Result<List<Category>> {
+        return Result.Success(MovieList.categories.map { name ->
             Category(
             Category(
                 name = name,
                 name = name,
                 movieList = getMovieListByCategory(name).unwrapOr(emptyList())
                 movieList = getMovieListByCategory(name).unwrapOr(emptyList())
@@ -26,22 +26,22 @@ class MovieAPI {
         })
         })
     }
     }
 
 
-    suspend fun loadFeaturedMovieList(): Option<List<Movie>> {
-        return Option.Some(MovieList.featured)
+    suspend fun loadFeaturedMovieList(): Result<List<Movie>> {
+        return Result.Success(MovieList.featured)
     }
     }
 
 
     suspend fun getMovieListByCategory(
     suspend fun getMovieListByCategory(
         category: String
         category: String
-    ): Option<List<Movie>> {
-        return Option.Some(MovieList.getByCategory(category))
+    ): Result<List<Movie>> {
+        return Result.Success(MovieList.getByCategory(category))
     }
     }
 
 
     suspend fun findMovieById(
     suspend fun findMovieById(
         id: Long
         id: Long
-    ): Option<Movie> {
+    ): Result<Movie> {
         return MovieList.findById(id).let { movie ->
         return MovieList.findById(id).let { movie ->
-            if (movie == null) Option.None
-            else Option.Some(movie)
+            if (movie == null) Result.Empty
+            else Result.Success(movie)
         }
         }
     }
     }
 
 

+ 0 - 25
app/src/main/kotlin/org/mjdev/tvapp/base/helpers/Option.kt

@@ -1,25 +0,0 @@
-/*
- * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
- */
-
-package org.mjdev.tvapp.base.helpers
-
-sealed class Option<out T> {
-
-    object None : Option<Nothing>()
-
-    data class Some<T>(val value: T) : Option<T>()
-
-    companion object {
-
-        fun <T> Option<T>.unwrapOr(defaultValue: T): T {
-            return (this as? Some)?.value ?: defaultValue
-        }
-
-    }
-
-}

+ 25 - 0
app/src/main/kotlin/org/mjdev/tvapp/base/helpers/Result.kt

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Milan Jurkulák 2023.
+ * Contact:
+ * e: mimoccc@gmail.com
+ * e: mj@mjdev.org
+ * w: https://mjdev.org
+ */
+
+package org.mjdev.tvapp.base.helpers
+
+sealed class Result<out T> {
+
+    object Empty : Result<Nothing>()
+
+    data class Success<T>(val value: T) : Result<T>()
+
+    companion object {
+
+        fun <T> Result<T>.unwrapOr(defaultValue: T): T {
+            return (this as? Success)?.value ?: defaultValue
+        }
+
+    }
+
+}

+ 1 - 0
app/src/main/kotlin/org/mjdev/tvapp/base/helpers/StateContextWrapper.kt

@@ -19,6 +19,7 @@ import androidx.savedstate.SavedStateRegistry
 import androidx.savedstate.SavedStateRegistryController
 import androidx.savedstate.SavedStateRegistryController
 import androidx.savedstate.SavedStateRegistryOwner
 import androidx.savedstate.SavedStateRegistryOwner
 
 
+// todo
 class StateContextWrapper(
 class StateContextWrapper(
     baseContext: Context
     baseContext: Context
 ) : ContextWrapper(baseContext) , LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {
 ) : ContextWrapper(baseContext) , LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/navigation/Screen.kt

@@ -102,7 +102,7 @@ open class Screen {
 
 
     /**
     /**
      * Compose function for compose screen.
      * Compose function for compose screen.
-     * This should be only a method overriden in super classes.
+     * This should be only a method overridden in super classes.
      *
      *
      * @param navController Nav controller
      * @param navController Nav controller
      * @param backStackEntry Back stack entry
      * @param backStackEntry Back stack entry

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/network/ConectivityCallback.kt → app/src/main/kotlin/org/mjdev/tvapp/base/network/ConnectivityCallback.kt

@@ -11,7 +11,7 @@ package org.mjdev.tvapp.base.network
 import android.net.ConnectivityManager
 import android.net.ConnectivityManager
 import android.net.Network
 import android.net.Network
 
 
-class ConectivityCallback(
+class ConnectivityCallback(
     val trySend: (data: NetworkStatus) -> Unit
     val trySend: (data: NetworkStatus) -> Unit
 ) : ConnectivityManager.NetworkCallback() {
 ) : ConnectivityManager.NetworkCallback() {
 
 

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/network/NetworkConnectivityServiceImpl.kt

@@ -27,7 +27,7 @@ class NetworkConnectivityServiceImpl constructor(
         .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
         .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
 
 
     override val networkStatus: Flow<NetworkStatus> = callbackFlow {
     override val networkStatus: Flow<NetworkStatus> = callbackFlow {
-        val connectivityCallback = ConectivityCallback { status ->
+        val connectivityCallback = ConnectivityCallback { status ->
             trySend(status)
             trySend(status)
         }
         }
         val request = NetworkRequest.Builder()
         val request = NetworkRequest.Builder()

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

@@ -1,83 +1,83 @@
-/*
- * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
- */
-
-package org.mjdev.tvapp.base.ui.components.complex
-
-import androidx.compose.foundation.border
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.width
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.focus.onFocusChanged
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-import androidx.tv.material3.ExperimentalTvMaterial3Api
-import androidx.tv.material3.ImmersiveList
-import org.mjdev.tvapp.base.interfaces.ItemWithImage
-import org.mjdev.tvapp.base.ui.components.image.ImageAny
-import timber.log.Timber
-
-// todo
-@OptIn(ExperimentalTvMaterial3Api::class)
-@Preview
-@Composable
-fun <T> ListWithPreview(
-    modifier: Modifier = Modifier,
-    items: List<T> = listOf(),
-    immersiveListHeight: Dp = 300.dp,
-    cardSpacing: Dp = 10.dp,
-    cardWidth: Dp = 200.dp,
-    cardHeight: Dp = 150.dp
-) {
-    val itemBackground: (index: Int) -> Any? = { index ->
-        (if (items.size > index)
-            (items[index] as? ItemWithImage?)?.backgroundImageUrl
-        else null) ?: Color.Transparent
-    }
-    ImmersiveList(
-        modifier = modifier
-            .height(immersiveListHeight + cardHeight / 2)
-            .fillMaxWidth(),
-        background = { index, _ ->
-            ImageAny(
-                modifier = Modifier
-                    .height(immersiveListHeight)
-                    .fillMaxWidth(),
-                src = itemBackground.invoke(index)
-            )
-        }
-    ) {
-        Row(horizontalArrangement = Arrangement.spacedBy(cardSpacing)) {
-            items.forEachIndexed { index, item ->
-                val isFocused = remember { mutableStateOf(false) }
-                ImageAny(
-                    modifier = Modifier
-                        .width(cardWidth)
-                        .height(cardHeight)
-                        .border(5.dp, Color.White.copy(alpha = if (isFocused.value) 1f else 0.3f))
-                        .onFocusChanged { focusState ->
-                            isFocused.value = focusState.isFocused
-                        }
-                        .immersiveListItem(index)
-                        .clickable {
-                            Timber.tag("ImmersiveList: Item $index was clicked")
-                        },
-                    src = itemBackground.invoke(index)
-                )
-            }
-        }
-    }
-}
+///*
+// * Copyright (c) Milan Jurkulák 2023.
+// * Contact:
+// * e: mimoccc@gmail.com
+// * e: mj@mjdev.org
+// * w: https://mjdev.org
+// */
+//
+//package org.mjdev.tvapp.base.ui.components.complex
+//
+//import androidx.compose.foundation.border
+//import androidx.compose.foundation.clickable
+//import androidx.compose.foundation.layout.Arrangement
+//import androidx.compose.foundation.layout.Row
+//import androidx.compose.foundation.layout.fillMaxWidth
+//import androidx.compose.foundation.layout.height
+//import androidx.compose.foundation.layout.width
+//import androidx.compose.runtime.Composable
+//import androidx.compose.runtime.mutableStateOf
+//import androidx.compose.runtime.remember
+//import androidx.compose.ui.Modifier
+//import androidx.compose.ui.focus.onFocusChanged
+//import androidx.compose.ui.graphics.Color
+//import androidx.compose.ui.tooling.preview.Preview
+//import androidx.compose.ui.unit.Dp
+//import androidx.compose.ui.unit.dp
+//import androidx.tv.material3.ExperimentalTvMaterial3Api
+//import androidx.tv.material3.ImmersiveList
+//import org.mjdev.tvapp.base.interfaces.ItemWithImage
+//import org.mjdev.tvapp.base.ui.components.image.ImageAny
+//import timber.log.Timber
+//
+//// todo
+//@OptIn(ExperimentalTvMaterial3Api::class)
+//@Preview
+//@Composable
+//fun <T> ListWithPreview(
+//    modifier: Modifier = Modifier,
+//    items: List<T> = listOf(),
+//    immersiveListHeight: Dp = 300.dp,
+//    cardSpacing: Dp = 10.dp,
+//    cardWidth: Dp = 200.dp,
+//    cardHeight: Dp = 150.dp
+//) {
+//    val itemBackground: (index: Int) -> Any? = { index ->
+//        (if (items.size > index)
+//            (items[index] as? ItemWithImage?)?.backgroundImageUrl
+//        else null) ?: Color.Transparent
+//    }
+//    ImmersiveList(
+//        modifier = modifier
+//            .height(immersiveListHeight + cardHeight / 2)
+//            .fillMaxWidth(),
+//        background = { index, _ ->
+//            ImageAny(
+//                modifier = Modifier
+//                    .height(immersiveListHeight)
+//                    .fillMaxWidth(),
+//                src = itemBackground.invoke(index)
+//            )
+//        }
+//    ) {
+//        Row(horizontalArrangement = Arrangement.spacedBy(cardSpacing)) {
+//            items.forEachIndexed { index, item ->
+//                val isFocused = remember { mutableStateOf(false) }
+//                ImageAny(
+//                    modifier = Modifier
+//                        .width(cardWidth)
+//                        .height(cardHeight)
+//                        .border(5.dp, Color.White.copy(alpha = if (isFocused.value) 1f else 0.3f))
+//                        .onFocusChanged { focusState ->
+//                            isFocused.value = focusState.isFocused
+//                        }
+//                        .immersiveListItem(index)
+//                        .clickable {
+//                            Timber.tag("ImmersiveList: Item $index was clicked")
+//                        },
+//                    src = itemBackground.invoke(index)
+//                )
+//            }
+//        }
+//    }
+//}

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

@@ -28,7 +28,7 @@ import org.mjdev.tvapp.base.state.ActivityViewState
 import org.mjdev.tvapp.base.state.ActivityViewState.Companion.rememberActivityViewState
 import org.mjdev.tvapp.base.state.ActivityViewState.Companion.rememberActivityViewState
 import org.mjdev.tvapp.base.ui.components.navigation.Navigation
 import org.mjdev.tvapp.base.ui.components.navigation.Navigation
 
 
-@Suppress("TrailingComma", "UNUSED_ANONYMOUS_PARAMETER")
+@Suppress("TrailingComma", "UNUSED_ANONYMOUS_PARAMETER", "unused")
 @TvPreview
 @TvPreview
 @Composable
 @Composable
 fun ScreenView(
 fun ScreenView(

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

@@ -27,7 +27,6 @@ import org.mjdev.tvapp.R
 import org.mjdev.tvapp.base.annotations.TvPreview
 import org.mjdev.tvapp.base.annotations.TvPreview
 import org.mjdev.tvapp.base.ui.components.text.TextAny
 import org.mjdev.tvapp.base.ui.components.text.TextAny
 
 
-@Suppress("LocalVariableName")
 @TvPreview
 @TvPreview
 @Composable
 @Composable
 fun Title(
 fun Title(

+ 12 - 1
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/image/ImageAny.kt

@@ -24,8 +24,10 @@ import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.graphics.asImageBitmap
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.tooling.preview.Preview
+import androidx.core.content.ContextCompat
 import coil.compose.AsyncImage
 import coil.compose.AsyncImage
 import org.mjdev.tvapp.R
 import org.mjdev.tvapp.R
 import org.mjdev.tvapp.base.extensions.DrawableExt.asImageBitmap
 import org.mjdev.tvapp.base.extensions.DrawableExt.asImageBitmap
@@ -48,10 +50,19 @@ fun ImageAny(
     modifier = modifier
     modifier = modifier
 ) {
 ) {
 
 
+    val width = constraints.maxWidth
+    val height = constraints.maxHeight
+
+    val context = LocalContext.current
+
+    val placeholderDrawable : Drawable = (placeholder?.let { ph ->
+        ContextCompat.getDrawable(context, ph)
+    } ?: ColorDrawable(0))
+
     when (src) {
     when (src) {
 
 
         null -> Image(
         null -> Image(
-            ColorDrawable(0).asImageBitmap(),
+            placeholderDrawable.asImageBitmap(width, height),
             contentDescription,
             contentDescription,
             modifier,
             modifier,
             alignment,
             alignment,

+ 0 - 3
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/navigation/Navigation.kt

@@ -84,7 +84,6 @@ fun Navigation(
 
 
                         NavigationRow(
                         NavigationRow(
                             id = SETTINGS_ITEM,
                             id = SETTINGS_ITEM,
-                            focused = (focused.value == SETTINGS_ITEM),
                             drawerValue = state,
                             drawerValue = state,
                             icon = Icons.Outlined.Settings,
                             icon = Icons.Outlined.Settings,
                             text = "Settings",
                             text = "Settings",
@@ -110,7 +109,6 @@ fun Navigation(
 
 
                         NavigationRow(
                         NavigationRow(
                             id = SEARCH_ITEM,
                             id = SEARCH_ITEM,
-                            focused = (focused.value == SEARCH_ITEM),
                             drawerValue = state,
                             drawerValue = state,
                             icon = Icons.Outlined.Search,
                             icon = Icons.Outlined.Search,
                             text = "Search",
                             text = "Search",
@@ -136,7 +134,6 @@ fun Navigation(
                     items.forEachIndexed { idx, menuItem ->
                     items.forEachIndexed { idx, menuItem ->
                         NavigationRow(
                         NavigationRow(
                             id = idx,
                             id = idx,
-                            focused = (focused.value == idx),
                             drawerValue = state,
                             drawerValue = state,
                             text = menuItem.menuText,
                             text = menuItem.menuText,
                             icon = menuItem.menuIcon,
                             icon = menuItem.menuIcon,

+ 0 - 2
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/navigation/NavigationRow.kt

@@ -30,13 +30,11 @@ import org.mjdev.tvapp.base.ui.components.complex.FocusableBox
 import org.mjdev.tvapp.base.ui.components.icon.IconAny
 import org.mjdev.tvapp.base.ui.components.icon.IconAny
 import org.mjdev.tvapp.base.ui.components.text.TextAny
 import org.mjdev.tvapp.base.ui.components.text.TextAny
 
 
-@Suppress("LocalVariableName")
 @Preview
 @Preview
 @OptIn(ExperimentalTvMaterial3Api::class)
 @OptIn(ExperimentalTvMaterial3Api::class)
 @Composable
 @Composable
 fun NavigationRow(
 fun NavigationRow(
     id: Int = -1,
     id: Int = -1,
-    focused: Boolean = false,
     drawerValue: DrawerValue = DrawerValue.Open,
     drawerValue: DrawerValue = DrawerValue.Open,
     text: Any? = "test",
     text: Any? = "test",
     icon: Any? = Icons.Default.AccountCircle,
     icon: Any? = Icons.Default.AccountCircle,

+ 3 - 2
app/src/main/kotlin/org/mjdev/tvapp/base/ui/components/text/CircleText.kt

@@ -43,7 +43,7 @@ fun CircleText(
     borderSize: Dp = 2.dp,
     borderSize: Dp = 2.dp,
     text: String = "0",
     text: String = "0",
     textColor: Color = Color.White,
     textColor: Color = Color.White,
-    textSize: TextUnit = 40.sp
+    textSize: TextUnit = 26.sp
 ) {
 ) {
 
 
     Box(
     Box(
@@ -78,7 +78,8 @@ fun CircleText(
             textAlign = TextAlign.Center,
             textAlign = TextAlign.Center,
             fontWeight = FontWeight.Bold,
             fontWeight = FontWeight.Bold,
             color = textColor,
             color = textColor,
-            text = text
+            text = text,
+            fontSize = textSize
         )
         )
 
 
     }
     }

+ 3 - 3
app/src/main/kotlin/org/mjdev/tvapp/repository/MovieRepository.kt

@@ -15,7 +15,7 @@ import kotlinx.coroutines.launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import kotlinx.coroutines.sync.withLock
 import org.mjdev.tvapp.api.MovieAPI
 import org.mjdev.tvapp.api.MovieAPI
-import org.mjdev.tvapp.base.helpers.Option.Companion.unwrapOr
+import org.mjdev.tvapp.base.helpers.Result.Companion.unwrapOr
 import org.mjdev.tvapp.data.Category
 import org.mjdev.tvapp.data.Category
 import org.mjdev.tvapp.data.Movie
 import org.mjdev.tvapp.data.Movie
 import java.lang.Integer.max
 import java.lang.Integer.max
@@ -39,7 +39,7 @@ class MovieRepository @Inject constructor(
     private val categoryListMutex = Mutex()
     private val categoryListMutex = Mutex()
 
 
     override suspend fun getFeaturedMovieList(): List<Movie> {
     override suspend fun getFeaturedMovieList(): List<Movie> {
-        val movieList = dataSource.loadFeaturedMovieList().unwrapOr(listOf<Movie>())
+        val movieList = dataSource.loadFeaturedMovieList().unwrapOr(listOf())
         updateCache(movieList)
         updateCache(movieList)
         return movieList
         return movieList
     }
     }
@@ -76,7 +76,7 @@ class MovieRepository @Inject constructor(
         if (force || !categoryMovieListMap.contains(category)) {
         if (force || !categoryMovieListMap.contains(category)) {
             updateCache(
             updateCache(
                 category = category,
                 category = category,
-                movieList = dataSource.getMovieListByCategory(category.name).unwrapOr(listOf<Movie>())
+                movieList = dataSource.getMovieListByCategory(category.name).unwrapOr(listOf())
             )
             )
         }
         }
     }
     }

+ 97 - 95
app/src/main/kotlin/org/mjdev/tvapp/ui/components/MyComposeView.kt

@@ -1,95 +1,97 @@
-/*
- * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
- */
-
-package org.mjdev.tvapp.ui.components;
-
-import android.content.Context
-import android.graphics.PixelFormat
-import android.view.Gravity
-import android.view.View
-import android.view.WindowManager
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.platform.AbstractComposeView
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.ViewModelStore
-import androidx.lifecycle.ViewModelStoreOwner
-import androidx.lifecycle.setViewTreeLifecycleOwner
-import androidx.lifecycle.setViewTreeViewModelStoreOwner
-import androidx.savedstate.SavedStateRegistry
-import androidx.savedstate.SavedStateRegistryController
-import androidx.savedstate.SavedStateRegistryOwner
-import androidx.savedstate.setViewTreeSavedStateRegistryOwner
-
-class MyComposeView(val composeView: View) : AbstractComposeView(
-    composeView.context
-), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {
-
-    private val savedStateRegistryController by lazy {
-        SavedStateRegistryController.create(this)
-    }
-
-    override val lifecycle: Lifecycle by lazy {
-        LifecycleRegistry(this)
-    }
-
-    override val viewModelStore: ViewModelStore by lazy {
-        ViewModelStore()
-    }
-
-    override val savedStateRegistry: SavedStateRegistry
-        get() = savedStateRegistryController.savedStateRegistry
-
-
-    private var viewShowing:Boolean = false
-
-    private fun handleLifecycleEvent(event: Lifecycle.Event) =
-        (lifecycle as LifecycleRegistry).handleLifecycleEvent(event)
-
-
-    private val windowManager by lazy {
-        composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
-    }
-
-    private var params: WindowManager.LayoutParams = WindowManager.LayoutParams()
-        .apply {
-            gravity = Gravity.TOP
-            type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
-            token = composeView.applicationWindowToken
-            width = WindowManager.LayoutParams.WRAP_CONTENT
-            height = WindowManager.LayoutParams.WRAP_CONTENT
-            format = PixelFormat.TRANSLUCENT
-            flags = flags or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-        }
-
-    init {
-        composeView.setViewTreeLifecycleOwner(this)
-        composeView.setViewTreeViewModelStoreOwner(this)
-        composeView.setViewTreeSavedStateRegistryOwner(this)
-    }
-
-    @Composable
-    override fun Content() {
-        // Some Compose Drawing Function
-    }
-
-    fun show() {
-        if (viewShowing) dismiss()
-        windowManager.addView(this, params)
-        viewShowing = true
-    }
-
-    fun dismiss() {
-        if (!viewShowing) return
-        disposeComposition()
-        windowManager.removeViewImmediate(this)
-        viewShowing = false
-    }
-
-}
+///*
+// * Copyright (c) Milan Jurkulák 2023.
+// * Contact:
+// * e: mimoccc@gmail.com
+// * e: mj@mjdev.org
+// * w: https://mjdev.org
+// */
+//
+//package org.mjdev.tvapp.ui.components
+//
+//import android.content.Context
+//import android.graphics.PixelFormat
+//import android.view.Gravity
+//import android.view.View
+//import android.view.WindowManager
+//import androidx.compose.runtime.Composable
+//import androidx.compose.ui.platform.AbstractComposeView
+//import androidx.lifecycle.Lifecycle
+//import androidx.lifecycle.LifecycleOwner
+//import androidx.lifecycle.LifecycleRegistry
+//import androidx.lifecycle.ViewModelStore
+//import androidx.lifecycle.ViewModelStoreOwner
+//import androidx.lifecycle.setViewTreeLifecycleOwner
+//import androidx.lifecycle.setViewTreeViewModelStoreOwner
+//import androidx.savedstate.SavedStateRegistry
+//import androidx.savedstate.SavedStateRegistryController
+//import androidx.savedstate.SavedStateRegistryOwner
+//import androidx.savedstate.setViewTreeSavedStateRegistryOwner
+//
+//class MyComposeView(
+//    val composeView: View
+//) : AbstractComposeView(
+//    composeView.context
+//), LifecycleOwner, ViewModelStoreOwner, SavedStateRegistryOwner {
+//
+//    private val savedStateRegistryController by lazy {
+//        SavedStateRegistryController.create(this)
+//    }
+//
+//    override val lifecycle: Lifecycle by lazy {
+//        LifecycleRegistry(this)
+//    }
+//
+//    override val viewModelStore: ViewModelStore by lazy {
+//        ViewModelStore()
+//    }
+//
+//    override val savedStateRegistry: SavedStateRegistry
+//        get() = savedStateRegistryController.savedStateRegistry
+//
+//
+//    private var viewShowing: Boolean = false
+//
+//    private fun handleLifecycleEvent(event: Lifecycle.Event) =
+//        (lifecycle as LifecycleRegistry).handleLifecycleEvent(event)
+//
+//
+//    private val windowManager by lazy {
+//        composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+//    }
+//
+//    private var params: WindowManager.LayoutParams = WindowManager.LayoutParams()
+//        .apply {
+//            gravity = Gravity.TOP
+//            type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
+//            token = composeView.applicationWindowToken
+//            width = WindowManager.LayoutParams.WRAP_CONTENT
+//            height = WindowManager.LayoutParams.WRAP_CONTENT
+//            format = PixelFormat.TRANSLUCENT
+//            flags = flags or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
+//        }
+//
+//    init {
+//        composeView.setViewTreeLifecycleOwner(this)
+//        composeView.setViewTreeViewModelStoreOwner(this)
+//        composeView.setViewTreeSavedStateRegistryOwner(this)
+//    }
+//
+//    @Composable
+//    override fun Content() {
+//        // Some Compose Drawing Function
+//    }
+//
+//    fun show() {
+//        if (viewShowing) dismiss()
+//        windowManager.addView(this, params)
+//        viewShowing = true
+//    }
+//
+//    fun dismiss() {
+//        if (!viewShowing) return
+//        disposeComposition()
+//        windowManager.removeViewImmediate(this)
+//        viewShowing = false
+//    }
+//
+//}

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

@@ -9,7 +9,7 @@
 package org.mjdev.tvapp.ui.screens
 package org.mjdev.tvapp.ui.screens
 
 
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material.icons.filled.Info
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.collectAsState
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.remember
@@ -44,7 +44,7 @@ class DetailScreen : Screen() {
 
 
     override val menuTitleResId: Int = -1
     override val menuTitleResId: Int = -1
 
 
-    override val menuIcon: ImageVector get() = Icons.Filled.ArrowBack
+    override val menuIcon: ImageVector get() = Icons.Filled.Info
 
 
     @TvPreview
     @TvPreview
     @Composable
     @Composable

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

@@ -62,13 +62,11 @@ class PlayerScreen : Screen() {
 
 
         val viewModel = appViewModel<DetailViewModel>()
         val viewModel = appViewModel<DetailViewModel>()
         val movieId: Long? = remember { args[movieId] as Long? }
         val movieId: Long? = remember { args[movieId] as Long? }
-        val movieState = remember {
-            viewModel?.detailsLoadingState(movieId)
-        }?.collectAsState()
+        val movieState = remember { viewModel.detailsLoadingState(movieId) }.collectAsState()
 
 
-        fun postError(error: String) = viewModel?.postError(error.asException())
+        fun postError(error: String) = viewModel.postError(error.asException())
 
 
-        when (movieState?.value) {
+        when (movieState.value) {
             is DetailsLoadingState.Ready -> MediaPlayer(
             is DetailsLoadingState.Ready -> MediaPlayer(
                 modifier = Modifier.fillMaxSize(),
                 modifier = Modifier.fillMaxSize(),
                 movie = (movieState.value as DetailsLoadingState.Ready).movie
                 movie = (movieState.value as DetailsLoadingState.Ready).movie

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

@@ -8,8 +8,37 @@
 
 
 package org.mjdev.tvapp.ui.screens
 package org.mjdev.tvapp.ui.screens
 
 
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Home
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.navigation.NavBackStackEntry
+import androidx.navigation.NavHostController
+import org.mjdev.tvapp.R
+import org.mjdev.tvapp.base.annotations.TvPreview
+import org.mjdev.tvapp.base.navigation.MenuItem
 import org.mjdev.tvapp.base.navigation.Screen
 import org.mjdev.tvapp.base.navigation.Screen
 
 
 class SplashScreen : Screen() {
 class SplashScreen : Screen() {
 
 
+    override val titleResId = R.string.app_name
+
+    override val menuTitleResId: Int = R.string.app_name
+
+    override val menuIcon: ImageVector get() = Icons.Filled.Home
+
+    @TvPreview
+    @Composable
+    override fun Compose() = super.Compose()
+
+    @Composable
+    override fun Compose(
+        navController: NavHostController?,
+        backStackEntry: NavBackStackEntry?,
+        menuItems: List<MenuItem>,
+        args: Map<String, Any?>
+    ) {
+
+    }
+
 }
 }

+ 2 - 2
app/src/main/kotlin/org/mjdev/tvapp/ui/screens/SubscriptionScreen.kt

@@ -9,7 +9,7 @@
 package org.mjdev.tvapp.ui.screens
 package org.mjdev.tvapp.ui.screens
 
 
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.material.icons.filled.ShoppingCart
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.navigation.NavBackStackEntry
 import androidx.navigation.NavBackStackEntry
@@ -25,7 +25,7 @@ class SubscriptionScreen : Screen() {
 
 
     override val menuTitleResId: Int = R.string.title_subscription
     override val menuTitleResId: Int = R.string.title_subscription
 
 
-    override val menuIcon: ImageVector get() = Icons.Filled.ArrowBack
+    override val menuIcon: ImageVector get() = Icons.Filled.ShoppingCart
 
 
     @TvPreview
     @TvPreview
     @Composable
     @Composable

BIN
buildSrc/.gradle/8.0/executionHistory/executionHistory.bin


BIN
buildSrc/.gradle/8.0/executionHistory/executionHistory.lock


BIN
buildSrc/.gradle/buildOutputCleanup/buildOutputCleanup.lock


BIN
buildSrc/.gradle/file-system.probe


BIN
buildSrc/build/classes/kotlin/main/META-INF/buildSrc.kotlin_module


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/extensions/DependencyHandlerKt.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/helper/CustomEventLogger.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$Companion.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$1.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$3.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$4.class


BIN
buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin.class


+ 1 - 0
buildSrc/build/kotlin/buildSrcjar-classes.txt

@@ -0,0 +1 @@
+/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/extensions/DependencyHandlerKt.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/helper/CustomEventLogger.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$Companion.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$1.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$3.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin$apply$4.class:/home/mimo/AndroidStudioProjects/tvapp/buildSrc/build/classes/kotlin/main/org/mjdev/gradle/plugin/MainAppPlugin.class

BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab.values.at


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/inputs/source-to-output.tab_i.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab.values.at


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-attributes.tab_i.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab.values.at


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/class-fq-name-to-source.tab_i.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab_i.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab.values.at


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab_i


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/inline-functions.tab_i.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.keystream.len


BIN
buildSrc/build/kotlin/compileKotlin/cacheable/caches-jvm/jvm/kotlin/internal-name-to-source.tab.len


Некоторые файлы не были показаны из-за большого количества измененных файлов