diff --git a/README.md b/README.md index c28de0ac9..bed900b3e 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ ## Latest releases 🛠 -- (Next Gen) Kotlin && Multiplatform && Plugin | [v10.8.2](https://github.com/mikepenz/AboutLibraries/tree/v10.8.2) +- (Next Gen) Kotlin && Multiplatform && Plugin | [v10.8.3](https://github.com/mikepenz/AboutLibraries/tree/v10.8.3) - Kotlin && Gradle Plugin | [v8.9.4](https://github.com/mikepenz/AboutLibraries/tree/v8.9.4) ## Gradle Plugin diff --git a/aboutlibraries-compose/build.gradle.kts b/aboutlibraries-compose/build.gradle.kts index a787ae272..667eae097 100644 --- a/aboutlibraries-compose/build.gradle.kts +++ b/aboutlibraries-compose/build.gradle.kts @@ -32,6 +32,21 @@ android { tasks.withType { kotlinOptions.jvmTarget = "11" + + kotlinOptions { + if (project.findProperty("composeCompilerReports") == "true") { + freeCompilerArgs += listOf( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_compiler" + ) + } + if (project.findProperty("composeCompilerMetrics") == "true") { + freeCompilerArgs += listOf( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_compiler" + ) + } + } } buildFeatures { @@ -98,6 +113,7 @@ dependencies { commonMainImplementation(compose.ui) commonMainImplementation(compose.foundation) commonMainImplementation(compose.material) + commonMainImplementation(libs.kotlinx.collections) debugImplementation(compose.uiTooling) "androidMainImplementation"(compose.preview) diff --git a/aboutlibraries-compose/src/androidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt b/aboutlibraries-compose/src/androidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt index aa962f36f..47a82ebcd 100644 --- a/aboutlibraries-compose/src/androidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt +++ b/aboutlibraries-compose/src/androidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt @@ -28,7 +28,9 @@ import androidx.core.text.HtmlCompat import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.entity.Library import com.mikepenz.aboutlibraries.ui.compose.data.fakeData +import com.mikepenz.aboutlibraries.ui.compose.util.StableLibrary import com.mikepenz.aboutlibraries.ui.compose.util.htmlReadyLicenseContent +import com.mikepenz.aboutlibraries.ui.compose.util.stable import com.mikepenz.aboutlibraries.util.withContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -63,7 +65,7 @@ fun LibrariesContainer( } } - val libs = libraries.value?.libraries + val libs = libraries.value?.libraries?.stable if (libs != null) { val openDialog = remember { mutableStateOf(null) } Libraries( @@ -93,7 +95,7 @@ fun LibrariesContainer( val library = openDialog.value if (library != null) { - LicenseDialog(library = library, colors) { + LicenseDialog(library = library.stable, colors) { openDialog.value = null } } @@ -102,7 +104,7 @@ fun LibrariesContainer( @Composable fun LicenseDialog( - library: Library, + library: StableLibrary, colors: LibraryColors = LibraryDefaults.libraryColors(), onDismiss: () -> Unit, ) { @@ -121,7 +123,7 @@ fun LicenseDialog( modifier = Modifier.verticalScroll(scrollState), ) { HtmlText( - html = library.licenses.firstOrNull()?.htmlReadyLicenseContent.orEmpty(), + html = library.library.licenses.firstOrNull()?.htmlReadyLicenseContent.orEmpty(), color = colors.contentColor, ) } @@ -147,7 +149,7 @@ fun HtmlText( fun PreviewLibraries() { MaterialTheme { Surface { - Libraries(fakeData.libraries) + Libraries(fakeData.libraries.stable) } } } @@ -158,7 +160,7 @@ fun PreviewLibraries() { fun PreviewLibrariesOff() { MaterialTheme { Surface { - Libraries(fakeData.libraries, showAuthor = false, showLicenseBadges = false) + Libraries(fakeData.libraries.stable, showAuthor = false, showLicenseBadges = false) } } } @@ -169,7 +171,7 @@ fun PreviewLibrary() { MaterialTheme { Surface { Library( - fakeData.libraries.first() + fakeData.libraries.first().stable ) { // on-click } diff --git a/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/SharedLibraries.kt b/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/SharedLibraries.kt index 7a7e7d047..a7cbdad48 100644 --- a/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/SharedLibraries.kt +++ b/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/SharedLibraries.kt @@ -2,22 +2,9 @@ package com.mikepenz.aboutlibraries.ui.compose import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.Badge -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.Typography -import androidx.compose.material.contentColorFor +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.* +import androidx.compose.material.* import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable @@ -30,14 +17,16 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.mikepenz.aboutlibraries.entity.Library +import com.mikepenz.aboutlibraries.ui.compose.util.StableLibrary import com.mikepenz.aboutlibraries.ui.compose.util.author +import kotlinx.collections.immutable.ImmutableList /** * Displays all provided libraries in a simple list. */ @Composable fun Libraries( - libraries: List, + libraries: ImmutableList, modifier: Modifier = Modifier, lazyListState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), @@ -80,7 +69,7 @@ fun Libraries( } internal inline fun LazyListScope.libraryItems( - libraries: List, + libraries: ImmutableList, showAuthor: Boolean = true, showVersion: Boolean = true, showLicenseBadges: Boolean = true, @@ -99,14 +88,14 @@ internal inline fun LazyListScope.libraryItems( padding, itemContentPadding ) { - onLibraryClick.invoke(library) + onLibraryClick.invoke(library.library) } } } @Composable internal fun Library( - library: Library, + library: StableLibrary, showAuthor: Boolean = true, showVersion: Boolean = true, showLicenseBadges: Boolean = true, @@ -128,7 +117,7 @@ internal fun Library( horizontalArrangement = Arrangement.SpaceBetween ) { Text( - text = library.name, + text = library.library.name, modifier = Modifier .padding(padding.namePadding) .weight(1f), @@ -137,7 +126,7 @@ internal fun Library( maxLines = 1, overflow = TextOverflow.Ellipsis ) - val version = library.artifactVersion + val version = library.library.artifactVersion if (version != null && showVersion) { Text( version, @@ -148,7 +137,7 @@ internal fun Library( ) } } - val author = library.author + val author = library.library.author if (showAuthor && author.isNotBlank()) { Text( text = author, @@ -156,9 +145,9 @@ internal fun Library( color = colors.contentColor ) } - if (showLicenseBadges && library.licenses.isNotEmpty()) { + if (showLicenseBadges && library.library.licenses.isNotEmpty()) { Row { - library.licenses.forEach { + library.library.licenses.forEach { Badge( modifier = Modifier.padding(padding.badgePadding), contentColor = colors.badgeContentColor, diff --git a/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/util/Extensions.kt b/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/util/Extensions.kt index 7fa52d03b..0935ccdbd 100644 --- a/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/util/Extensions.kt +++ b/aboutlibraries-compose/src/commonMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/util/Extensions.kt @@ -1,7 +1,18 @@ package com.mikepenz.aboutlibraries.ui.compose.util +import androidx.compose.runtime.Immutable import com.mikepenz.aboutlibraries.entity.Library import com.mikepenz.aboutlibraries.entity.License +import kotlinx.collections.immutable.toImmutableList +import kotlin.jvm.JvmInline + +@JvmInline +@Immutable +value class StableLibrary(val library: Library) + +val Library.stable get() = StableLibrary(this) + +val List.stable get() = map { it.stable }.toImmutableList() val Library.author: String get() = developers.takeIf { it.isNotEmpty() }?.map { it.name }?.joinToString(", ") ?: organization?.name ?: "" diff --git a/aboutlibraries-compose/src/nonAndroidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt b/aboutlibraries-compose/src/nonAndroidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt index 61bfb6b77..8dd1094fc 100644 --- a/aboutlibraries-compose/src/nonAndroidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt +++ b/aboutlibraries-compose/src/nonAndroidMain/kotlin/com/mikepenz/aboutlibraries/ui/compose/Libraries.kt @@ -11,6 +11,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.entity.Library +import com.mikepenz.aboutlibraries.ui.compose.util.stable import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -75,7 +76,7 @@ fun LibrariesContainer( } } - val libs = libraries.value?.libraries + val libs = libraries.value?.libraries?.stable if (libs != null) { Libraries( libraries = libs, diff --git a/gradle.properties b/gradle.properties index 2fee23f9e..9a009a118 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ GROUP=com.mikepenz -VERSION_NAME=10.8.2 -VERSION_CODE=100820 +VERSION_NAME=10.8.3 +VERSION_CODE=100830 POM_URL=https://github.com/mikepenz/AboutLibraries POM_SCM_URL=https://github.com/mikepenz/AboutLibraries POM_SCM_CONNECTION=scm:git@github.com:mikepenz/AboutLibraries.git diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e34f61ff7..55e68dc37 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,6 +12,7 @@ dokka = "1.8.20" kotlinCore = { require = "1.8.22" } kotlinCoroutines = { require = "1.7.2" } kotlinxSerialization = "1.5.1" +kotlinxCollections = "0.3.5" # compose compose = "1.4.3" composeUi = "1.4.3" # foundation / material @@ -48,6 +49,7 @@ kotlin-plug = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.re kotlin-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinCoroutines" } kotlin-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinCoroutines" } kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" } +kotlinx-collections = { module = "org.jetbrains.kotlinx:kotlinx-collections-immutable", version.ref = "kotlinxCollections" } # compose compose-androidx-runtime-core = { module = "androidx.compose.runtime:runtime", version.ref = "compose" } compose-androidx-runtime-livedata = { module = "androidx.compose.runtime:runtime-livedata", version.ref = "compose" } diff --git a/plugin-build/plugin/src/main/kotlin/com/mikepenz/aboutlibraries/plugin/mapping/SpdxLicense.kt b/plugin-build/plugin/src/main/kotlin/com/mikepenz/aboutlibraries/plugin/mapping/SpdxLicense.kt index 17442ef93..4ce4fabdb 100644 --- a/plugin-build/plugin/src/main/kotlin/com/mikepenz/aboutlibraries/plugin/mapping/SpdxLicense.kt +++ b/plugin-build/plugin/src/main/kotlin/com/mikepenz/aboutlibraries/plugin/mapping/SpdxLicense.kt @@ -9,7 +9,7 @@ enum class SpdxLicense( val id: String, val customUrl: String? = null, val customTxtUrl: String? = null, - val customMatcher: ((name: String, url: String?) -> Boolean)? = null + val customMatcher: ((name: String, url: String?) -> Boolean)? = null, ) { _0BSD("BSD Zero Clause License", "0BSD"), AAL("Attribution Assurance License", "AAL"), @@ -60,7 +60,10 @@ enum class SpdxLicense( BSD_3_Clause_Clear("BSD 3-Clause Clear License", "BSD-3-Clause-Clear"), BSD_3_Clause_LBNL("Lawrence Berkeley National Labs BSD variant license", "BSD-3-Clause-LBNL"), BSD_3_Clause_No_Nuclear_License("BSD 3-Clause No Nuclear License", "BSD-3-Clause-No-Nuclear-License"), - BSD_3_Clause_No_Nuclear_License_2014("BSD 3-Clause No Nuclear License 2014", "BSD-3-Clause-No-Nuclear-License-2014"), + BSD_3_Clause_No_Nuclear_License_2014( + "BSD 3-Clause No Nuclear License 2014", + "BSD-3-Clause-No-Nuclear-License-2014" + ), BSD_3_Clause_No_Nuclear_Warranty("BSD 3-Clause No Nuclear Warranty", "BSD-3-Clause-No-Nuclear-Warranty"), BSD_3_Clause_Open_MPI("BSD 3-Clause Open MPI variant", "BSD-3-Clause-Open-MPI"), BSD_4_Clause("BSD 4-Clause \"Original\" or \"Old\" License", "BSD-4-Clause"), @@ -118,7 +121,10 @@ enum class SpdxLicense( ClArtistic("Clarified Artistic License", "ClArtistic"), CNRI_Jython("CNRI Jython License", "CNRI-Jython"), CNRI_Python("CNRI Python License", "CNRI-Python"), - CNRI_Python_GPL_Compatible("CNRI Python Open Source GPL Compatible License Agreement", "CNRI-Python-GPL-Compatible"), + CNRI_Python_GPL_Compatible( + "CNRI Python Open Source GPL Compatible License Agreement", + "CNRI-Python-GPL-Compatible" + ), Condor_1_1("Condor Public License v1.1", "Condor-1.1"), copyleft_next_0_3_0("copyleft-next 0.3.0", "copyleft-next-0.3.0"), copyleft_next_0_3_1("copyleft-next 0.3.1", "copyleft-next-0.3.1"), @@ -233,7 +239,10 @@ enum class SpdxLicense( MPL_1_0("Mozilla Public License 1.0", "MPL-1.0"), MPL_1_1("Mozilla Public License 1.1", "MPL-1.1"), MPL_2_0("Mozilla Public License 2.0", "MPL-2.0"), - MPL_2_0_no_copyleft_exception("Mozilla Public License 2.0 (no copyleft exception)", "MPL-2.0-no-copyleft-exception"), + MPL_2_0_no_copyleft_exception( + "Mozilla Public License 2.0 (no copyleft exception)", + "MPL-2.0-no-copyleft-exception" + ), MS_PL("Microsoft Public License", "MS-PL"), MS_RL("Microsoft Reciprocal License", "MS-RL"), MTLL("Matrix Template Library License", "MTLL"), @@ -382,7 +391,7 @@ enum class SpdxLicense( ZPL_2_1("Zope Public License 2.1", "ZPL-2.1"), // Special handling section - Apache_2_0("Apache License 2.0", "Apache-2.0", "apache_2_0", customMatcher = { name, url -> + Apache_2_0("Apache License 2.0", "Apache-2.0", customMatcher = { name, url -> name.contains("Apache", true) || url?.endsWith("LICENSE-2.0.txt") == true }), BSD_2_Clause("BSD 2-Clause \"Simplified\" License", "BSD-2-Clause", customMatcher = { name, url -> @@ -391,13 +400,16 @@ enum class SpdxLicense( || url?.endsWith("opensource.org/licenses/bsd-license", true) == true }), BSD_3_Clause("BSD 3-Clause \"New\" or \"Revised\" License", "BSD-3-Clause", customMatcher = { name, url -> - name.equals("New BSD License", true) || name.equals("Modified BSD License", true) || name.equals("BSD 3-clause", true) || + name.equals("New BSD License", true) || name.equals("Modified BSD License", true) || name.equals( + "BSD 3-clause", + true + ) || url?.endsWith("opensource.org/licenses/BSD-3-Clause", true) == true }), - MIT("MIT License", "MIT", "mit", customMatcher = { name, _ -> + MIT("MIT License", "MIT", customMatcher = { name, _ -> name.contains("MIT", true) }), - CC0_1_0("Creative Commons Zero v1.0 Universal", "CC0-1.0", "cc0_1_0", customMatcher = { name, _ -> + CC0_1_0("Creative Commons Zero v1.0 Universal", "CC0-1.0", customMatcher = { name, _ -> name.equals("CC0", true) }), JSON("JSON License", "JSON", customMatcher = { name, _ -> @@ -411,7 +423,11 @@ enum class SpdxLicense( ASDKL("Android Software Development Kit License", "ASDKL"), CTS("Crashlytics Terms of Service", "CTS"), FSSA("Fabric Software and Services Agreement", "FSSA"), - GPL_2_0_CPE("GNU General Public License, version 2, with the Classpath Exception", "GPL-2.0-CPE", customUrl = "https://openjdk.org/legal/gplv2+ce.html"); + GPL_2_0_CPE( + "GNU General Public License, version 2, with the Classpath Exception", + "GPL-2.0-CPE", + customUrl = "https://openjdk.org/legal/gplv2+ce.html" + ); fun getUrl(): String = customUrl ?: "https://spdx.org/licenses/$id.html"