Skip to content

Commit

Permalink
chore: revert to KatanaResources
Browse files Browse the repository at this point in the history
  • Loading branch information
alvr committed Mar 4, 2024
1 parent 21c5202 commit 28219ba
Show file tree
Hide file tree
Showing 14 changed files with 164 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.alvr.katana.buildlogic

internal const val AndroidDir = "src/androidMain"
internal const val ResourcesDir = "src/commonMain/resources"

internal const val ANDROID_APPLICATION_PLUGIN = "com.android.application"
internal const val ANDROID_LIBRARY_PLUGIN = "com.android.library"
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.gradle.jvm.toolchain.JvmVendorSpec
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.getByType
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions
Expand Down Expand Up @@ -89,6 +90,11 @@ internal fun BaseExtension.configureAndroid(packageName: String) {
targetCompatibility = KatanaConfiguration.UseJavaVersion
}

with(sourceSets["main"]) {
res.srcDirs("$AndroidDir/res", ResourcesDir)
resources.srcDirs(ResourcesDir)
}

testOptions {
animationsDisabled = true
unitTests {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import dev.alvr.katana.buildlogic.ANDROID_APPLICATION_PLUGIN
import dev.alvr.katana.buildlogic.AndroidDir
import dev.alvr.katana.buildlogic.KatanaConfiguration
import dev.alvr.katana.buildlogic.ResourcesDir
import dev.alvr.katana.buildlogic.catalogBundle
import dev.alvr.katana.buildlogic.configureAndroid
import dev.alvr.katana.buildlogic.mp.mobile.KatanaMultiplatformMobileBasePlugin
Expand Down Expand Up @@ -119,6 +120,7 @@ internal class KatanaMultiplatformAppPlugin : KatanaMultiplatformMobileBasePlugi

sourceSets["main"].manifest.srcFile("$AndroidDir/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("$AndroidDir/res")
sourceSets["main"].resources.srcDirs(ResourcesDir)
}

private fun SentryPluginExtension.configureSentry() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package dev.alvr.katana.buildlogic.mp.mobile.ui

import dev.alvr.katana.buildlogic.ResourcesDir
import dev.alvr.katana.buildlogic.catalogBundle
import dev.alvr.katana.buildlogic.catalogLib
import dev.alvr.katana.buildlogic.fullPackageName
import dev.alvr.katana.buildlogic.kspDependencies
import dev.alvr.katana.buildlogic.mp.androidUnitTest
import dev.alvr.katana.buildlogic.mp.configureSourceSets
import dev.alvr.katana.buildlogic.mp.tasks.GenerateResourcesFileTask
import java.io.File
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.ExtensionAware
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.registering
import org.jetbrains.compose.ComposeExtension
import org.jetbrains.compose.ComposePlugin
import org.jetbrains.compose.ExperimentalComposeLibrary
Expand All @@ -28,6 +33,8 @@ internal class KatanaMultiplatformComposePlugin : Plugin<Project> {
configure<KotlinMultiplatformExtension> { configureMultiplatform() }
configure<ComposeExtension> { configureComposeMultiplatform() }
}

generateResourcesTask()
}

context(Project)
Expand All @@ -43,6 +50,8 @@ internal class KatanaMultiplatformComposePlugin : Plugin<Project> {

configureSourceSets {
commonMain {
kotlin.srcDirs("build/$GeneratedResourcesDir")

dependencies {
implementation(compose.animation)
implementation(compose.components.resources)
Expand Down Expand Up @@ -93,9 +102,27 @@ internal class KatanaMultiplatformComposePlugin : Plugin<Project> {
)
}

private fun Project.generateResourcesTask() {
val generateResourcesFile by tasks.registering(GenerateResourcesFileTask::class) {
packageName.set(fullPackageName)
inputFiles.from(
layout.projectDirectory.dir(ResourcesDir).asFileTree.matching {
include("**/*.webp", "**/*.xml")
},
)
outputDir.set(layout.buildDirectory.dir(GeneratedResourcesDir))
}

tasks.named("preBuild").configure { dependsOn(generateResourcesFile) }
}

private fun Project.composePluginEnabled(property: String) =
providers.gradleProperty(property).orNull == "true"

private fun Project.composePluginDir(directory: String) =
File(layout.buildDirectory.asFile.get(), directory).absolutePath

private companion object {
const val GeneratedResourcesDir = "generated/sources/katana/main"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package dev.alvr.katana.buildlogic.mp.tasks

import com.squareup.kotlinpoet.AnnotationSpec
import com.squareup.kotlinpoet.ClassName
import com.squareup.kotlinpoet.FileSpec
import com.squareup.kotlinpoet.KModifier
import com.squareup.kotlinpoet.PropertySpec
import com.squareup.kotlinpoet.TypeSpec
import dev.alvr.katana.buildlogic.ResourcesDir
import dev.alvr.katana.buildlogic.mp.identifier
import java.io.File
import org.gradle.api.DefaultTask
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.FileUtils

@CacheableTask
internal abstract class GenerateResourcesFileTask : DefaultTask() {
@get:Input
internal abstract val packageName: Property<String>

@get:InputFiles
@get:PathSensitive(value = PathSensitivity.RELATIVE)
internal abstract val inputFiles: ConfigurableFileCollection

@get:OutputDirectory
internal abstract val outputDir: DirectoryProperty

private val String.resourceIdentifier
get() = split('_').identifier

@TaskAction
private fun generateResourcesFile() {
inputFiles.files.generateResourcesFile()
}

private fun Set<File>.generateResourcesFile() {
if (isEmpty()) {
outputDir.get().asFile.deleteRecursively()
return
}

val stableAnnotation = AnnotationSpec
.builder(ClassName(ComposeRuntimePackage, ComposeStableAnnotation))
.build()

val properties = map { file ->
val propertyName = FileUtils.removeExtension(file.name).resourceIdentifier
val fileName = file.absolutePath.replace('\\', '/').substringAfter("$ResourcesDir/")

PropertySpec.builder(propertyName, ClassName(KatanaResourcePackage, KatanaResourceClass))
.addAnnotation(stableAnnotation)
.addModifiers(KModifier.INTERNAL)
.initializer("%L(%S)", KatanaResourceClass, fileName)
.build()
}

val resourcesObject = TypeSpec.objectBuilder(KatanaResourcesLocalClass)
.addModifiers(KModifier.INTERNAL)
.addProperties(properties)
.build()

FileSpec.builder(ClassName("${packageName.get()}$KatanaResourcesLocalPackage", KatanaResourcesLocalClass))
.addType(resourcesObject)
.build()
.writeTo(outputDir.get().asFile)
}

private companion object {
const val ComposeRuntimePackage = "androidx.compose.runtime"
const val ComposeStableAnnotation = "Stable"

const val KatanaResourcePackage = "dev.alvr.katana.core.ui.resources"
const val KatanaResourceClass = "KatanaResource"

const val KatanaResourcesLocalPackage = ".resources"
const val KatanaResourcesLocalClass = "KatanaResources"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.alvr.katana.core.ui.resources

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.saveable.Saver
import kotlin.jvm.JvmInline
import kotlinx.coroutines.runBlocking
import org.jetbrains.compose.resources.DrawableResource
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.InternalResourceApi
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.readResourceBytes

@Immutable
@JvmInline
value class KatanaResource(private val key: String) {

@OptIn(ExperimentalResourceApi::class)
val asPainter @Composable get() = painterResource(DrawableResource(key))

@OptIn(ExperimentalResourceApi::class, InternalResourceApi::class)
val asByteArray get() = runBlocking { readResourceBytes(key) }

val id get() = key.substringAfterLast('/').substringBeforeLast('.')

companion object {
val saver = Saver<KatanaResource, String>(
save = { res -> res.key },
restore = { key -> KatanaResource(key) }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ import dev.alvr.katana.core.common.zero
import dev.alvr.katana.core.ui.components.KatanaPullRefresh
import dev.alvr.katana.core.ui.modifiers.katanaPlaceholder
import dev.alvr.katana.features.lists.ui.entities.MediaListItem
import dev.alvr.katana.features.lists.ui.generated.resources.Res
import dev.alvr.katana.features.lists.ui.generated.resources.default_cover
import dev.alvr.katana.features.lists.ui.resources.KatanaResources
import dev.alvr.katana.features.lists.ui.strings.LocalListsStrings
import dev.alvr.katana.features.lists.ui.viewmodel.ListState
import io.kamel.image.KamelImage
Expand Down Expand Up @@ -266,7 +265,7 @@ private fun Cover(
onFailure = {
Image(
modifier = Modifier.align(Alignment.Center),
painter = painterResource(Res.drawable.default_cover),
painter = KatanaResources.defaultCover.asPainter,
contentDescription = LocalListsStrings.current.errorCover,
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ import dev.alvr.katana.features.login.ui.LOGIN_DEEP_LINK
import dev.alvr.katana.features.login.ui.LOGO_FULL_SIZE
import dev.alvr.katana.features.login.ui.LOGO_RESIZED
import dev.alvr.katana.features.login.ui.generated.resources.Res
import dev.alvr.katana.features.login.ui.generated.resources.background_chihiro
import dev.alvr.katana.features.login.ui.generated.resources.background_howl
import dev.alvr.katana.features.login.ui.generated.resources.background_mononoke
import dev.alvr.katana.features.login.ui.generated.resources.background_totoro
import dev.alvr.katana.features.login.ui.generated.resources.ic_katana_logo
import dev.alvr.katana.features.login.ui.resources.KatanaResources
import dev.alvr.katana.features.login.ui.navigation.LoginNavigator
import dev.alvr.katana.features.login.ui.strings.LocalLoginStrings
import dev.alvr.katana.features.login.ui.viewmodel.LoginState
Expand Down Expand Up @@ -118,10 +114,10 @@ private fun Login(state: LoginState, onLogin: () -> Unit) {

val background = remember {
listOf(
Res.drawable.background_chihiro,
Res.drawable.background_howl,
Res.drawable.background_mononoke,
Res.drawable.background_totoro,
KatanaResources.backgroundChihiro,
KatanaResources.backgroundHowl,
KatanaResources.backgroundMononoke,
KatanaResources.backgroundTotoro,
).random()
}

Expand Down Expand Up @@ -153,7 +149,7 @@ private fun Login(state: LoginState, onLogin: () -> Unit) {
Loading()
} else {
Image(
painter = painterResource(background),
painter = background.asPainter,
contentDescription = strings.contentDescriptionBackground,
contentScale = ContentScale.Crop,
modifier = Modifier
Expand Down Expand Up @@ -202,7 +198,7 @@ private fun KatanaLogo() {
}

Image(
painter = painterResource(Res.drawable.ic_katana_logo),
painter = KatanaResources.icKatanaLogo.asPainter,
contentDescription = LocalLoginStrings.current.contentDescriptionKatanaLogo,
modifier = Modifier
.padding(top = 8.dp)
Expand Down

0 comments on commit 28219ba

Please sign in to comment.