diff --git a/build.gradle.kts b/build.gradle.kts index 35bc5897..5ec87bd1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ plugins { + alias(libs.plugins.aboutLibraries) apply false alias(libs.plugins.androidApplication) apply false alias(libs.plugins.androidLibrary) apply false alias(libs.plugins.jetbrainsCompose) apply false @@ -15,4 +16,4 @@ tasks.wrapper { gradleVersion = "8.10.2" distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-bin.zip" distributionSha256Sum = "31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26" -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index adefae35..7c570ce9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,4 +1,5 @@ [versions] +aboutlibraries = "11.4.0" agp = "8.7.1" android-compileSdk = "35" android-minSdk = "24" @@ -94,7 +95,10 @@ android-svg = { module = "com.caverock:androidsvg-aar", version.ref = "android-s coil-compose = { module = "io.coil-kt.coil3:coil-compose", version.ref = "coil" } coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", version.ref = "coil" } +aboutlibraries-compose = { module = "com.mikepenz:aboutlibraries-compose", version.ref = "aboutlibraries" } + [plugins] +aboutLibraries = { id= "com.mikepenz.aboutlibraries.plugin", version.ref="aboutlibraries"} androidApplication = { id = "com.android.application", version.ref = "agp" } androidLibrary = { id = "com.android.library", version.ref = "agp" } jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 5d0205d8..691fe9a4 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -1,6 +1,9 @@ +import com.mikepenz.aboutlibraries.plugin.DuplicateMode +import com.mikepenz.aboutlibraries.plugin.DuplicateRule import org.jetbrains.kotlin.compose.compiler.gradle.ComposeFeatureFlag plugins { + alias(libs.plugins.aboutLibraries) alias(libs.plugins.androidLibrary) alias(libs.plugins.jetbrainsCompose) alias(libs.plugins.kotlinParcelize) @@ -71,6 +74,8 @@ kotlin { implementation(libs.androidx.navigation.compose) implementation(libs.ktor.client.core) + + implementation(libs.aboutlibraries.compose) } commonTest.dependencies { @@ -167,3 +172,8 @@ val buildWebApp by tasks.creating(Copy::class) { composeCompiler { featureFlags.add(ComposeFeatureFlag.OptimizeNonSkippingGroups) } + +aboutLibraries { + duplicationMode = DuplicateMode.MERGE + duplicationRule = DuplicateRule.SIMPLE +} diff --git a/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/App.kt b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/App.kt index 49ff5159..c9ee786f 100644 --- a/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/App.kt +++ b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/App.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlinconf.screens.AboutAppScreen import org.jetbrains.kotlinconf.screens.AboutConference import org.jetbrains.kotlinconf.screens.CodeOfConduct import org.jetbrains.kotlinconf.screens.InfoScreen +import org.jetbrains.kotlinconf.screens.LicensesScreen import org.jetbrains.kotlinconf.screens.PartnerDetails import org.jetbrains.kotlinconf.screens.Partners import org.jetbrains.kotlinconf.screens.PrivacyPolicyForVisitors @@ -97,6 +98,7 @@ fun App(context: ApplicationContext) { StyledText("Partners", Modifier.clickable { navController.navigate(PartnersScreen) }) StyledText("Schedule", Modifier.clickable { navController.navigate(ScheduleScreen) }) StyledText("Speakers", Modifier.clickable { navController.navigate(SpeakersScreen) }) + StyledText("Licenses", Modifier.clickable { navController.navigate(LicensesScreen) }) } } composable { @@ -172,6 +174,9 @@ fun App(context: ApplicationContext) { val sessionId = it.toRoute().talkId Session(service.sessionById(sessionId)) } + composable { + LicensesScreen(onBack = navController::popBackStack) + } } } } diff --git a/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/navigation.kt b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/navigation.kt index 4006f97e..1244ee2f 100644 --- a/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/navigation.kt +++ b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/navigation.kt @@ -59,6 +59,9 @@ data class TalkDetailsScreen(val talkId: SessionId) @Serializable data object SpeakersScreen +@Serializable +data object LicensesScreen + @Serializable data class SpeakerDetailsScreen(val speakerId: SpeakerId) diff --git a/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/screens/LicensesScreen.kt b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/screens/LicensesScreen.kt new file mode 100644 index 00000000..193a3f48 --- /dev/null +++ b/shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/screens/LicensesScreen.kt @@ -0,0 +1,39 @@ +package org.jetbrains.kotlinconf.screens + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.mikepenz.aboutlibraries.ui.compose.LibrariesContainer +import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults +import com.mikepenz.aboutlibraries.ui.compose.rememberLibraries +import kotlinconfapp.shared.generated.resources.Res +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.kotlinconf.ScreenWithTitle +import org.jetbrains.kotlinconf.ui.theme.KotlinConfTheme + +@Composable +fun LicensesScreen( + onBack: () -> Unit, +) { + ScreenWithTitle(title = "Licenses", onBack = onBack) { + val libraries = rememberLibraries { + // To update licenses: + // gradlew :shared:exportLibraryDefinitions -PaboutLibraries.exportPath=src/commonMain/composeResources/files + @OptIn(ExperimentalResourceApi::class) + Res.readBytes("files/aboutlibraries.json").decodeToString() + }.value + + if (libraries != null) { + LibrariesContainer( + { libraries }, + Modifier.weight(1f), + colors = LibraryDefaults.libraryColors( + backgroundColor = KotlinConfTheme.colors.mainBackground, + contentColor = KotlinConfTheme.colors.primaryText, + badgeBackgroundColor = KotlinConfTheme.colors.tileBackground, + badgeContentColor = KotlinConfTheme.colors.secondaryText, + dialogConfirmButtonColor = KotlinConfTheme.colors.accentText, + ) + ) + } + } +}