Ver código fonte

code improvements

code improvements

code improvements

code improvements

code improvements
Milan Jurkulak 2 anos atrás
pai
commit
38a919a1f7
57 arquivos alterados com 250 adições e 183 exclusões
  1. 30 2
      app/build.gradle.kts
  2. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/data/remote/Epg.kt
  3. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/data/remote/Stream.kt
  4. 37 37
      app/src/main/kotlin/org/mjdev/tvapp/database/DAO.kt
  5. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/module/ProvideModule.kt
  6. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/sync/SyncAdapter.kt
  7. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/sync/auth/AuthenticatorService.kt
  8. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/sync/base/SyncItems.kt
  9. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/sync/base/Syncer.kt
  10. 3 2
      app/src/main/kotlin/org/mjdev/tvapp/sync/syncers/GithubMoviesSyncer.kt
  11. 5 8
      app/src/main/kotlin/org/mjdev/tvapp/ui/pages/MainPage.kt
  12. 5 5
      app/src/main/kotlin/org/mjdev/tvapp/ui/screens/MainScreen.kt
  13. 18 5
      app/src/main/kotlin/org/mjdev/tvapp/viewmodel/DetailViewModel.kt
  14. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/viewmodel/IPTVViewModel.kt
  15. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/viewmodel/MainViewModel.kt
  16. 1 1
      app/src/main/kotlin/org/mjdev/tvapp/widget/MainAppWidget.kt
  17. 0 2
      buildSrc/build.gradle.kts
  18. 1 2
      buildSrc/src/main/kotlin/org/mjdev/gradle/base/BasePlugin.kt
  19. 21 29
      buildSrc/src/main/kotlin/org/mjdev/gradle/extensions/BuildTypeExt.kt
  20. 12 5
      buildSrc/src/main/kotlin/org/mjdev/gradle/extensions/ProjectExt.kt
  21. 20 29
      buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/AppPlugin.kt
  22. 14 12
      buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/LibPlugin.kt
  23. 31 1
      buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/config/AppConfig.kt
  24. 2 1
      buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/config/LibConfig.kt
  25. 2 1
      tvlib/build.gradle.kts
  26. 2 2
      tvlib/src/main/kotlin/org/mjdev/tvlib/activity/ComposableActivity.kt
  27. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/application/TvApplication.kt
  28. 8 0
      tvlib/src/main/kotlin/org/mjdev/tvlib/events/util/ILogger.kt
  29. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/ApplicationGlideApp.kt
  30. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/LoaderTarget.kt
  31. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/OkHttpUrlLoaderEx.kt
  32. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/m3u/M3ULoaderFactory.kt
  33. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/qrcode/QRCodeRes.kt
  34. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/svg/SvgDecoder.kt
  35. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/svg/SvgDrawableTranscoder.kt
  36. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/brush/BrushBuilder.kt
  37. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/brush/SquashedOval.kt
  38. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/cursor/AudioCursor.kt
  39. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/http/UserAgentInterceptor.kt
  40. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/media/ItemType.kt
  41. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/other/Observed.kt
  42. 0 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/other/Preferences.kt
  43. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemPhoto.kt
  44. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemVideo.kt
  45. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithBackground.kt
  46. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithDate.kt
  47. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithDescription.kt
  48. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithId.kt
  49. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithImage.kt
  50. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithIntent.kt
  51. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithMessage.kt
  52. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithSubtitle.kt
  53. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithTitle.kt
  54. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithUri.kt
  55. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/viewmodel/BaseViewModel.kt
  56. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/webscrapper/adblock/IAdBlocker.kt
  57. 1 1
      tvlib/src/main/kotlin/org/mjdev/tvlib/webscrapper/adblock/NoAdBlock.kt

+ 30 - 2
app/build.gradle.kts

@@ -12,7 +12,35 @@ plugins {
 
 appConfig {
     autoCorrectCode = false
-    createDocumentation = true
+    createDocumentation = false
     createReleaseNotes = true
-    createZipRelease = true
+    createZipRelease = false
+
+    default {
+//        buildConfigString(
+//            "IPTV_API_URL" to "https://iptv-org.github.io/api/",
+//            "GITHUB_USER" to "mimoccc",
+//            "GITHUB_REPOSITORY" to "tvapp"
+//        )
+//        manifestPlaceholders(
+//            "auth0Domain" to "@string/com_auth0_domain",
+//            "auth0Scheme" to "demo"
+//        )
+    }
+
+    debug {
+//        stringRes("app_name", "TVApp-Debug")
+//        addSyncProviderAuthString("sync_auth", "sync")
+    }
+
+    release {
+//        stringRes("app_name", "TVApp")
+//        addSyncProviderAuthString("sync_auth", "sync")
+    }
+
+    minified {
+//        stringRes("app_name", "TVApp-Minified")
+//        addSyncProviderAuthString("sync_auth", "sync")
+    }
+
 }

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/data/remote/Epg.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/data/remote/Stream.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 37 - 37
app/src/main/kotlin/org/mjdev/tvapp/database/DAO.kt

@@ -16,17 +16,19 @@ import io.objectbox.kotlin.boxFor
 import org.mjdev.tvapp.BuildConfig
 import org.mjdev.tvapp.data.local.Category
 import org.mjdev.tvapp.data.local.Country
-import org.mjdev.tvapp.data.local.Message
 import org.mjdev.tvapp.data.local.Media
+import org.mjdev.tvapp.data.local.Message
 import org.mjdev.tvapp.data.local.MyObjectBox
 import org.mjdev.tvapp.data.local.ParsedLink
 import org.mjdev.tvapp.data.local.TVChannel
-import kotlin.reflect.KClass
 
 @Suppress("unused", "MemberVisibilityCanBePrivate")
 class DAO(
     @ApplicationContext
     val context: Context,
+    val isDebug: Boolean = false,
+    // todo
+    val autoDeleteDatabaseOnSchemaError: Boolean = true,
 ) {
 
     companion object {
@@ -34,55 +36,53 @@ class DAO(
     }
 
     private val store: BoxStore by lazy {
-        MyObjectBox.builder()
-            .androidContext(context)
-            .name(DATABASE_NAME)
-            .build()
+        buildStore()
     }
 
-    val cache = mutableMapOf<KClass<*>, List<*>>()
-
-    val movieDao: Box<Media> by lazy {
-        store.boxFor()
-    }
+    val movieDao: Box<Media>
+        get() = store.boxFor()
 
     @Suppress("unused")
-    val categoryDao: Box<Category> by lazy {
-        store.boxFor()
-    }
+    val categoryDao: Box<Category> get() = store.boxFor()
 
     @Suppress("unused")
-    val channelsDao: Box<TVChannel> by lazy {
-        store.boxFor()
-    }
+    val channelsDao: Box<TVChannel>
+        get() = store.boxFor()
 
-    val messagesDao: Box<Message> by lazy {
-        store.boxFor()
-    }
+    val messagesDao: Box<Message>
+        get() = store.boxFor()
 
-    val countriesDao: Box<Country> by lazy {
-        store.boxFor()
-    }
+    val countriesDao: Box<Country>
+        get() = store.boxFor()
 
-    val parsedLinksDao: Box<ParsedLink> by lazy {
-        store.boxFor()
-    }
+    val parsedLinksDao: Box<ParsedLink>
+        get() = store.boxFor()
 
-    val allMediaItems: List<Any> by lazy {
-        movieDao.all
-    }
+    val allMediaItems: List<Any>
+        get() = movieDao.all
 
-    val parsedLinks: List<ParsedLink> by lazy {
-        parsedLinksDao.all
-    }
+    val parsedLinks: List<ParsedLink>
+        get() = parsedLinksDao.all
 
-    inline fun <reified T> getCachedList(creator: () -> List<*>): List<*> {
-        if (!cache.containsKey(T::class)) {
-            creator().let { list ->
-                cache[T::class] = list
+    private fun buildStore(): BoxStore {
+        return MyObjectBox.builder()
+            .androidContext(context)
+            .name(DATABASE_NAME)
+            .apply {
+//                if (isDebug) {
+//                    debugFlags(1023)
+//                    debugRelations()
+//                }
             }
+            .build()
+    }
+
+    private fun clearStore() {
+        synchronized(store) {
+            store.close()
+            store.removeAllObjects()
+//            store.deleteAllFiles()
         }
-        return cache[T::class] ?: emptyList<Any>()
     }
 
 }

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/module/ProvideModule.kt

@@ -46,7 +46,7 @@ class ProvideModule {
     fun provideDAO(
         @ApplicationContext
         context: Context
-    ): DAO = DAO(context)
+    ): DAO = DAO(context, BuildConfig.DEBUG)
 
     @Singleton
     @Provides

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/sync/SyncAdapter.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/sync/auth/AuthenticatorService.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/sync/base/SyncItems.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
app/src/main/kotlin/org/mjdev/tvapp/sync/base/Syncer.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 3 - 2
app/src/main/kotlin/org/mjdev/tvapp/sync/syncers/GithubMoviesSyncer.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org
@@ -47,13 +47,14 @@ class GithubMoviesSyncer(
             }
         }
 
+        // todo if exists
         with(SyncItems(oldMovies, newMovies)) {
             toAdd.forEach { movie ->
                 try {
                     dao.movieDao.stx { put(movie) }
                     Timber.d("Movie: $movie stored.")
                 } catch (e: Exception) {
-                    Timber.e(e)
+//                    Timber.e(e)
                 }
             }
 

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

@@ -1,9 +1,9 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
+ *  Copyright (c) Milan Jurkulák 2024.
+ *  Contact:
+ *  e: mimoccc@gmail.com
+ *  e: mj@mjdev.org
+ *  w: https://mjdev.org
  */
 
 package org.mjdev.tvapp.ui.pages
@@ -12,7 +12,6 @@ import android.annotation.SuppressLint
 import android.net.Uri
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Home
 import androidx.compose.runtime.Composable
@@ -25,7 +24,6 @@ import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.unit.dp
 import org.mjdev.tvapp.BuildConfig
 import org.mjdev.tvapp.R
 import org.mjdev.tvapp.activity.IPTVActivity
@@ -48,7 +46,6 @@ import org.mjdev.tvlib.extensions.NavExt.rememberNavControllerEx
 import org.mjdev.tvlib.interfaces.ItemPhoto
 import org.mjdev.tvlib.interfaces.ItemWithBackground
 import org.mjdev.tvlib.interfaces.ItemWithImage
-import org.mjdev.tvlib.ui.dialog.BlurDialog
 import java.io.Serializable
 import java.net.URL
 

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

@@ -1,9 +1,9 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
- * Contact:
- * e: mimoccc@gmail.com
- * e: mj@mjdev.org
- * w: https://mjdev.org
+ *  Copyright (c) Milan Jurkulák 2024.
+ *  Contact:
+ *  e: mimoccc@gmail.com
+ *  e: mj@mjdev.org
+ *  w: https://mjdev.org
  */
 
 package org.mjdev.tvapp.ui.screens

+ 18 - 5
app/src/main/kotlin/org/mjdev/tvapp/viewmodel/DetailViewModel.kt

@@ -28,6 +28,8 @@ import javax.inject.Inject
 @HiltViewModel
 class DetailViewModel @Inject constructor() : BaseViewModel() {
 
+//    private val cache = mutableMapOf<KClass<*>, List<*>>()
+
     @Inject
     lateinit var dao: DAO
 
@@ -40,13 +42,24 @@ class DetailViewModel @Inject constructor() : BaseViewModel() {
     @Inject
     lateinit var localPhotoCursor: PhotoCursor
 
+    // todo : improve on changes
+    inline fun <reified T> getCachedList(creator: () -> List<*>): List<*> {
+//        if (!cache.containsKey(T::class)) {
+//            creator().let { list ->
+//                cache[T::class] = list
+//            }
+//        }
+//        return cache[T::class] ?: emptyList<Any>()
+        return creator()
+    }
+
     fun mediaItemsFor(
         data: Any?
     ): List<Any?> = when (data) {
-        is ItemAudio -> dao.getCachedList<ItemAudio> { localAudioCursor }
-        is ItemVideo -> dao.getCachedList<ItemVideo> { localVideoCursor }
-        is ItemPhoto -> dao.getCachedList<ItemPhoto> { localPhotoCursor }
-        is Media -> dao.getCachedList<Media> { dao.allMediaItems }
+        is ItemAudio -> getCachedList<ItemAudio> { localAudioCursor }
+        is ItemVideo -> getCachedList<ItemVideo> { localVideoCursor }
+        is ItemPhoto -> getCachedList<ItemPhoto> { localPhotoCursor }
+        is Media -> getCachedList<Media> { dao.allMediaItems }
         else -> listOf(data.mediaItem)
     }
 
@@ -56,7 +69,7 @@ class DetailViewModel @Inject constructor() : BaseViewModel() {
         fun mock(
             context: Context
         ): DetailViewModel = DetailViewModel().apply {
-            dao = DAO(context)
+            dao = DAO(context, true)
             localAudioCursor = AudioCursor(context)
             localVideoCursor = VideoCursor(context)
             localPhotoCursor = PhotoCursor(context)

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

@@ -79,7 +79,7 @@ class IPTVViewModel @Inject constructor() : BaseViewModel() {
         fun mock(
             context: Context
         ): IPTVViewModel = IPTVViewModel().apply {
-            dao = DAO(context)
+            dao = DAO(context, true)
             networkInfo = NetworkConnectivityService(context)
             localAudioCursor = AudioCursor(context)
             localVideoCursor = VideoCursor(context)

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

@@ -105,7 +105,7 @@ class MainViewModel @Inject constructor() : BaseViewModel() {
         fun mock(
             context: Context
         ): MainViewModel = MainViewModel().apply {
-            dao = DAO(context)
+            dao = DAO(context, true)
             localAudioCursor = AudioCursor(context)
             localVideoCursor = VideoCursor(context)
             localPhotoCursor = PhotoCursor(context)

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

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 0 - 2
buildSrc/build.gradle.kts

@@ -68,8 +68,6 @@ dependencies {
     implementation(libs.gradle.detekt.plugin)
     implementation(libs.gradle.dokka.plugin)
     implementation(libs.gradle.kotlinter)
-//    implementation(libs.ktoml.core)
-//    implementation(libs.ktoml.file)
     implementation(libs.jsoup)
     implementation(libs.kotlin.stdlib.jdk8)
     implementation(libs.detekt.formatting)

+ 1 - 2
buildSrc/src/main/kotlin/org/mjdev/gradle/base/BasePlugin.kt

@@ -20,7 +20,6 @@ abstract class BasePlugin : Plugin<Project> {
 
     abstract fun Project.work()
 
-    operator fun <T> NamedDomainObjectCollection<T>.get(index:String) =
-        getByName(index)
+    operator fun <T> NamedDomainObjectCollection<T>.get(index:String) = findByName(index)
 
 }

+ 21 - 29
buildSrc/src/main/kotlin/org/mjdev/gradle/extensions/VariantDimension.kt → buildSrc/src/main/kotlin/org/mjdev/gradle/extensions/BuildTypeExt.kt

@@ -11,7 +11,8 @@
 package org.mjdev.gradle.extensions
 
 import com.android.build.api.dsl.ApplicationVariantDimension
-import kotlin.String
+
+typealias BuildTypeFnc = ApplicationVariantDimension.() -> Unit
 
 fun ApplicationVariantDimension.buildConfigBoolean(
     vararg fields: Pair<String, Boolean>
@@ -29,18 +30,6 @@ fun ApplicationVariantDimension.buildConfigString(
     }
 }
 
-fun ApplicationVariantDimension.buildConfigStringWithPackageName(
-    vararg fields: Pair<String, String>
-) {
-    fields.forEach { pair ->
-        buildConfigField(
-            "String",
-            pair.first,
-            "APPLICATION_ID + " + "\".${pair.second}\""
-        )
-    }
-}
-
 fun ApplicationVariantDimension.stringRes(
     vararg fields: Pair<String, String>
 ) {
@@ -56,8 +45,17 @@ fun ApplicationVariantDimension.stringRes(
     resValue("string", name, value)
 }
 
+fun ApplicationVariantDimension.addSyncProviderAuthString(
+    applicationId:String,
+    name: String = "sync_auth",
+    suffix: String = "sync"
+) {
+    buildConfigStringWithPackageName(name.uppercase() to suffix)
+    stringResWithPackageName(applicationId, name to suffix)
+}
+
 fun ApplicationVariantDimension.stringResWithPackageName(
-    applicationId: String,
+    applicationId:String,
     vararg fields: Pair<String, String>
 ) {
     fields.forEach { pair ->
@@ -65,24 +63,18 @@ fun ApplicationVariantDimension.stringResWithPackageName(
     }
 }
 
-fun ApplicationVariantDimension.addSyncProviderAuthString(
-    applicationId: String,
-    name: String = "sync_auth",
-    suffix: String = "sync"
+fun ApplicationVariantDimension.buildConfigStringWithPackageName(
+    vararg fields: Pair<String, String>
 ) {
-    buildConfigStringWithPackageName(name.uppercase() to suffix)
-    stringResWithPackageName(applicationId, name to suffix)
+    fields.forEach { pair ->
+        buildConfigField(
+            "String",
+            pair.first,
+            "APPLICATION_ID + " + "\".${pair.second}\""
+        )
+    }
 }
 
-//fun ApplicationVariantDimension.createSuffixedStringRes(
-//    name: String,
-//    base: String
-//) {
-//    val suffix = if(applicationIdSuffix.isNullOrEmpty()) ""
-//    else ( " - "  + applicationIdSuffix.suffixToString())
-//    resValue("string", name, base + suffix)
-//}
-
 fun ApplicationVariantDimension.manifestPlaceholders(
     vararg fields: Pair<String, Any>
 ) {

+ 12 - 5
buildSrc/src/main/kotlin/org/mjdev/gradle/extensions/ProjectExt.kt

@@ -312,8 +312,15 @@ fun Project.fileTree(directory: String, inc: String, exc: String): List<File> {
     }.toList()
 }
 
-//fun Project.androidComponents(
-//    block: AndroidComponentsExtension<*, *, *>.() -> Unit
-//) {
-//    block.invoke(androidComponents)
-//}
+inline fun <reified T> Project.runConfigured(crossinline function: T.() -> Unit) {
+    afterEvaluate {
+        val config = project.extension<T>()
+        function(config)
+    }
+}
+
+fun Project.androidComponents(
+    block: AndroidComponentsExtension<*, *, *>.() -> Unit
+) {
+    block.invoke(androidComponents)
+}

+ 20 - 29
buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/AppPlugin.kt

@@ -48,6 +48,7 @@ import org.mjdev.gradle.extensions.dokkaTask
 import org.mjdev.gradle.extensions.apply
 import org.mjdev.gradle.extensions.projectName
 import org.mjdev.gradle.extensions.loadPropertiesFile
+import org.mjdev.gradle.extensions.runConfigured
 import org.mjdev.gradle.plugin.config.AppConfig
 import org.mjdev.gradle.tasks.ReleaseNotesCleanTask
 import org.mjdev.gradle.tasks.ReleaseNotesCreateTask
@@ -82,9 +83,9 @@ class AppPlugin : BasePlugin() {
     override fun Project.work() {
         extension<AppConfig>(configFieldName)
         loadPropertiesFile(versionPropertiesFile)
-        apply(plugin = "version-catalog")
-        apply(plugin = "kotlin-android")
+//        apply(plugin = "version-catalog")
         apply(plugin = "com.android.application")
+        apply(plugin = "kotlin-android")
         apply(plugin = "kotlin-kapt")
         apply(plugin = "kotlin-parcelize")
         apply(plugin = "com.google.devtools.ksp")
@@ -158,12 +159,6 @@ class AppPlugin : BasePlugin() {
                     isMinifyEnabled = false
                     isShrinkResources = false
                     isCrunchPngs = false
-//                  isEmbedMicroApp = true
-//                  isPseudoLocalesEnabled = true
-//                  enableUnitTestCoverage = true
-//                  enableAndroidTestCoverage = true
-//                  isRenderscriptDebuggable = true
-//                  isZipAlignEnabled = false
                     signingConfig = signingConfigs[name]
                     stringRes("app_name", "TVApp-Debug")
                     addSyncProviderAuthString(
@@ -183,12 +178,6 @@ class AppPlugin : BasePlugin() {
                     isMinifyEnabled = true
                     isShrinkResources = true
                     isCrunchPngs = true
-//                  isEmbedMicroApp = true
-//                  isPseudoLocalesEnabled = false
-//                  enableUnitTestCoverage = false
-//                  enableAndroidTestCoverage = false
-//                  isRenderscriptDebuggable = false
-//                  isZipAlignEnabled = true
                     signingConfig = signingConfigs[name]
                     // todo : move
                     stringRes("app_name", "TVApp")
@@ -225,8 +214,7 @@ class AppPlugin : BasePlugin() {
                 jacocoVersion = libs.versions.jacoco.version.string
             }
         }
-        afterEvaluate {
-            val appConfig = project.extension<AppConfig>()
+        runConfigured<AppConfig> {
             kotlinCompileOptions {
                 kotlinOptions {
                     freeCompilerArgs += "-Xjsr305=strict"
@@ -234,19 +222,19 @@ class AppPlugin : BasePlugin() {
                 }
             }
             detektTask {
-                if (appConfig.autoCorrectCode)
+                if (autoCorrectCode)
                     runAfterAssembleTask()
             }
             dokkaTask {
-                outputDirectory.set(rootDir.resolve(appConfig.documentationDir))
+                outputDirectory.set(rootDir.resolve(documentationDir))
                 moduleName.set(projectName)
                 suppressObviousFunctions.set(false)
                 dokkaSourceSets.configureEach {
                     offlineMode.set(false)
                     includeNonPublic.set(false)
                     skipDeprecated.set(false)
-                    failOnWarning.set(appConfig.failOnDocumentationWarning)
-                    reportUndocumented.set(appConfig.reportUndocumentedFiles)
+                    failOnWarning.set(failOnDocumentationWarning)
+                    reportUndocumented.set(reportUndocumentedFiles)
                     skipEmptyPackages.set(false)
                     platform.set(Platform.jvm)
                     jdkVersion.set(projectJavaVersion.asInt())
@@ -254,36 +242,38 @@ class AppPlugin : BasePlugin() {
                     noJdkLink.set(false)
                     noAndroidSdkLink.set(false)
                 }
-                if (appConfig.createDocumentation)
+                if (createDocumentation)
                     runAfterAssembleTask()
             }
             val rnTask = registerTask<ReleaseNotesCreateTask> {
-                if (appConfig.createReleaseNotes)
+                if (createReleaseNotes)
                     runAfterAssembleTask()
             }
             registerTask<ZipReleaseCreateTask> {
-                if (appConfig.createReleaseNotes)
+                if (createReleaseNotes)
                     mustRunAfter(rnTask)
-                if (appConfig.createZipRelease)
+                if (createZipRelease)
                     runAfterAssembleTask()
             }
             configure<DetektExtension> {
-                ignoreFailures = appConfig.ignoreCodeFailures
-                reportsDir = rootDir.resolve(appConfig.codeReportsDir)
+                ignoreFailures = ignoreCodeFailures
+                reportsDir = rootDir.resolve(codeReportsDir)
                 @Suppress("DEPRECATION")
-                config = files(project.rootDir.resolve(appConfig.detectConfigFile))
+                config = files(project.rootDir.resolve(detectConfigFile))
             }
             configure<KotlinterExtension> {
-                ignoreFailures = appConfig.ignoreCodeFailures
+                ignoreFailures = ignoreCodeFailures
                 reporters = arrayOf("checkstyle", "plain")
             }
+// todo
 //            configurations.getByName("releaseRuntimeClasspath") {
 //                resolutionStrategy.activateDependencyLocking()
 //            }
+// todo
 //            configurations.getByName("debugRuntimeClasspath") {
 //                resolutionStrategy.activateDependencyLocking()
 //            }
-            // todo
+// todo
 //            if (appConfig.renameApkOutputByAppID) {
 //                applicationVariants.all {
 //                    outputs.map {
@@ -295,6 +285,7 @@ class AppPlugin : BasePlugin() {
 //                }
 //            }
         }
+// todo
 //        dependencyLocking {
 //            lockMode.set(LockMode.STRICT)
 //        }

+ 14 - 12
buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/LibPlugin.kt

@@ -38,6 +38,8 @@ import org.mjdev.gradle.extensions.apply
 import org.mjdev.gradle.extensions.int
 import org.mjdev.gradle.extensions.string
 import org.mjdev.gradle.extensions.projectName
+import org.mjdev.gradle.extensions.runConfigured
+import org.mjdev.gradle.plugin.config.AppConfig
 
 @Suppress("UnstableApiUsage")
 class LibPlugin : BasePlugin() {
@@ -112,7 +114,8 @@ class LibPlugin : BasePlugin() {
                     )
                 }
                 release {
-                    isMinifyEnabled = true
+                    // todo minify
+                    isMinifyEnabled = false
                     isShrinkResources = false
                     proguardFiles(
                         getDefaultProguardFile(projectProguardFile),
@@ -140,8 +143,7 @@ class LibPlugin : BasePlugin() {
                 jacocoVersion = libs.versions.jacoco.version.string
             }
         }
-        afterEvaluate {
-            val libConfig = project.extension<LibConfig>()
+        runConfigured<LibConfig> {
             kotlinCompileOptions{
                 kotlinOptions {
                     freeCompilerArgs += "-Xjsr305=strict"
@@ -149,19 +151,19 @@ class LibPlugin : BasePlugin() {
                 }
             }
             detektTask {
-                if (libConfig.autoCorrectCode)
+                if (autoCorrectCode)
                     runAfterAssembleTask()
             }
             dokkaTask {
-                outputDirectory.set(rootDir.resolve(libConfig.documentationDir))
+                outputDirectory.set(rootDir.resolve(documentationDir))
                 moduleName.set(projectName)
                 suppressObviousFunctions.set(false)
                 dokkaSourceSets.configureEach {
                     offlineMode.set(false)
                     includeNonPublic.set(false)
                     skipDeprecated.set(false)
-                    failOnWarning.set(libConfig.failOnDocumentationWarning)
-                    reportUndocumented.set(libConfig.reportUndocumentedFiles)
+                    failOnWarning.set(failOnDocumentationWarning)
+                    reportUndocumented.set(reportUndocumentedFiles)
                     skipEmptyPackages.set(false)
                     platform.set(Platform.jvm)
                     jdkVersion.set(projectJavaVersion.asInt())
@@ -169,17 +171,17 @@ class LibPlugin : BasePlugin() {
                     noJdkLink.set(false)
                     noAndroidSdkLink.set(false)
                 }
-                if (libConfig.createDocumentation)
+                if (createDocumentation)
                     runAfterAssembleTask()
             }
             configure<DetektExtension> {
-                reportsDir = rootDir.resolve(libConfig.codeReportsDir)
-                ignoreFailures = libConfig.ignoreCodeFailures
+                reportsDir = rootDir.resolve(codeReportsDir)
+                ignoreFailures = ignoreCodeFailures
                 @Suppress("DEPRECATION")
-                config = files(project.rootDir.resolve(libConfig.detectConfigFile))
+                config = files(project.rootDir.resolve(detectConfigFile))
             }
             configure<KotlinterExtension> {
-                ignoreFailures = libConfig.ignoreCodeFailures
+                ignoreFailures = ignoreCodeFailures
                 reporters = arrayOf("checkstyle", "plain")
             }
 //            configurations.getByName("releaseRuntimeClasspath") {

+ 31 - 1
buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/config/AppConfig.kt

@@ -8,8 +8,13 @@
 
 package org.mjdev.gradle.plugin.config
 
+import org.mjdev.gradle.extensions.BuildTypeFnc
+
 open class AppConfig {
-    open var autoCorrectCode = true
+
+    private val buildTypes = mutableMapOf<String, BuildTypeFnc>()
+
+    open var autoCorrectCode = false
     open var ignoreCodeFailures = true
     open var createDocumentation = false
     open var reportUndocumentedFiles = false
@@ -24,4 +29,29 @@ open class AppConfig {
     open var codeReportsDir = "reports/app"
     open var documentationDir = "documentation/app"
     open var detectConfigFile = "config/detekt.yml"
+
+    fun default (action:BuildTypeFnc) {
+        buildTypes.put("debug", action)
+    }
+
+    fun debug(action: BuildTypeFnc) {
+        buildTypes.put("debug", action)
+    }
+
+    fun release(action: BuildTypeFnc) {
+        buildTypes.put("release", action)
+    }
+
+    fun minified(action: BuildTypeFnc) {
+        buildTypes.put("minified", action)
+    }
+
+    fun test(action: BuildTypeFnc) {
+        buildTypes.put("test", action)
+    }
+
+    fun publish(action: BuildTypeFnc) {
+        buildTypes.put("test", action)
+    }
+
 }

+ 2 - 1
buildSrc/src/main/kotlin/org/mjdev/gradle/plugin/config/LibConfig.kt

@@ -9,11 +9,12 @@
 package org.mjdev.gradle.plugin.config
 
 open class LibConfig {
-    open var autoCorrectCode = true
+    open var autoCorrectCode = false
     open var ignoreCodeFailures = true
     open var createDocumentation = false
     open var reportUndocumentedFiles = false
     open var failOnDocumentationWarning = false
+    open var minify = false
 
     open var codeReportsDir = "reports/lib"
     open var documentationDir = "documentation/lib"

+ 2 - 1
tvlib/build.gradle.kts

@@ -12,5 +12,6 @@ plugins {
 
 libConfig {
     autoCorrectCode = false
-    createDocumentation = true
+    createDocumentation = false
+    minify = false
 }

+ 2 - 2
tvlib/src/main/kotlin/org/mjdev/tvlib/activity/ComposableActivity.kt

@@ -70,8 +70,8 @@ open class ComposableActivity : ComponentActivity() {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
             setDecorFitsSystemWindows(window, false)
             window.setFlags(
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN,
-                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
+                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
             )
         } else {
             setDecorFitsSystemWindows(window, true)

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/application/TvApplication.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 8 - 0
tvlib/src/main/kotlin/org/mjdev/tvlib/events/util/ILogger.kt

@@ -1,3 +1,11 @@
+/*
+ *  Copyright (c) Milan Jurkulák 2024.
+ *  Contact:
+ *  e: mimoccc@gmail.com
+ *  e: mj@mjdev.org
+ *  w: https://mjdev.org
+ */
+
 package org.mjdev.tvlib.events.util
 
 import java.util.logging.Level

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/ApplicationGlideApp.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/LoaderTarget.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/OkHttpUrlLoaderEx.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/m3u/M3ULoaderFactory.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/qrcode/QRCodeRes.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/svg/SvgDecoder.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/glide/sources/svg/SvgDrawableTranscoder.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/brush/BrushBuilder.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/brush/SquashedOval.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/cursor/AudioCursor.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/http/UserAgentInterceptor.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023. 
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/media/ItemType.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/other/Observed.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 0 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/helpers/other/Preferences.kt

@@ -9,7 +9,6 @@
 package org.mjdev.tvlib.helpers.other
 
 import android.annotation.SuppressLint
-import android.content.Context
 import android.content.SharedPreferences
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemPhoto.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemVideo.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithBackground.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithDate.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithDescription.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithId.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithImage.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithIntent.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithMessage.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithSubtitle.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithTitle.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/interfaces/ItemWithUri.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/viewmodel/BaseViewModel.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/webscrapper/adblock/IAdBlocker.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org

+ 1 - 1
tvlib/src/main/kotlin/org/mjdev/tvlib/webscrapper/adblock/NoAdBlock.kt

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) Milan Jurkulák 2023.
+ *  Copyright (c) Milan Jurkulák 2024.
  *  Contact:
  *  e: mimoccc@gmail.com
  *  e: mj@mjdev.org