From 1cf576a59b5ba8ff788f1ae63b93bdbe6e09ca8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Kwiecin=CC=81ski?= Date: Mon, 20 Nov 2023 11:58:37 +0200 Subject: [PATCH] Build release app --- .github/workflows/default.yml | 2 +- gradle/libs.versions.toml | 2 +- licensee-for-android/build.gradle | 9 +- sample/app/build.gradle | 16 +- .../kotlin/se/premex/gross/MainActivity.kt | 17 ++- .../kotlin/se/premex/gross/OssArtifactView.kt | 32 ++-- .../se/premex/gross/OssKotlinCodeView.kt | 9 +- .../kotlin/se/premex/gross/ui/theme/Theme.kt | 13 -- sample/build.gradle | 1 + sample/gradle/libs.versions.toml | 4 +- sample/keys/debug.keystore | Bin 0 -> 2570 bytes sample/serialization/build.gradle | 2 +- .../main/kotlin/se/premex/gross/ui/OssView.kt | 137 ++++++++++-------- .../kotlin/se/premex/gross/ui/OssViewModel.kt | 6 +- 14 files changed, 139 insertions(+), 111 deletions(-) create mode 100644 sample/keys/debug.keystore diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index c3333c5..cbb8d65 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -101,7 +101,7 @@ jobs: with: build-root-directory: sample gradle-version: ${{ matrix.gradle }} - arguments: check -PagpVersion=${{ matrix.agp }} --continue + arguments: build -PagpVersion=${{ matrix.agp }} --continue - name: Upload reports if: ${{ failure() }} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 953c57f..3c831e7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,7 +19,7 @@ assertj-core = { module = "org.assertj:assertj-core", version.ref = "maven-asser agp-gradle-api = { module = "com.android.tools.build:gradle-api", version.ref = "google-agp" } kotlin-gradle-api = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin-api", version.ref = "maven-kotlin" } com-squareup-kotlinpoet = "com.squareup:kotlinpoet:1.15.1" -kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "maven-kotlin-serialization" } +kotlinx-serialization-json-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "maven-kotlin-serialization" } kotlinx-serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "maven-kotlin-serialization" } com-squareup-okio = "com.squareup.okio:okio:3.6.0" jetbrains-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "maven-dokka" } diff --git a/licensee-for-android/build.gradle b/licensee-for-android/build.gradle index b2897a8..37f255c 100644 --- a/licensee-for-android/build.gradle +++ b/licensee-for-android/build.gradle @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion plugins { id("java-gradle-plugin") @@ -15,7 +16,7 @@ dependencies { implementation(libs.com.squareup.kotlinpoet) { exclude(module: "kotlin-reflect") } - implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.serialization.json.core) implementation(libs.kotlinx.serialization.json.okio) implementation(libs.com.squareup.okio) @@ -32,9 +33,9 @@ kotlin { } tasks.withType(KotlinCompile).configureEach { - kotlinOptions { - apiVersion = "1.8" - languageVersion = "1.8" + compilerOptions { + apiVersion = KotlinVersion.KOTLIN_1_8 + languageVersion = KotlinVersion.KOTLIN_1_8 } } tasks.withType(Test).configureEach { diff --git a/sample/app/build.gradle b/sample/app/build.gradle index b72bdfa..d1fde63 100644 --- a/sample/app/build.gradle +++ b/sample/app/build.gradle @@ -2,6 +2,7 @@ plugins { alias(libs.plugins.starter.application.android) alias(libs.plugins.app.cash.licensee) id("io.github.usefulness.licensee-for-android") + alias(libs.plugins.starter.easylauncher) } licensee { @@ -20,10 +21,23 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } - + signingConfigs { + named("debug") { + storeFile rootProject.file("keys/debug.keystore") + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' + } + } buildTypes { + named("debug") { + signingConfig signingConfigs.getByName("debug") + applicationIdSuffix ".debug" + versionNameSuffix "-debug" + } named("release") { minifyEnabled = true + signingConfig signingConfigs.getByName("debug") proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") matchingFallbacks += ["debug"] } diff --git a/sample/app/src/main/kotlin/se/premex/gross/MainActivity.kt b/sample/app/src/main/kotlin/se/premex/gross/MainActivity.kt index 1700d49..e77f40d 100644 --- a/sample/app/src/main/kotlin/se/premex/gross/MainActivity.kt +++ b/sample/app/src/main/kotlin/se/premex/gross/MainActivity.kt @@ -3,6 +3,7 @@ package io.githhub.usefulness.licensee.android.app import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons @@ -14,8 +15,10 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import se.premex.gross.AssetsOssView @@ -30,17 +33,19 @@ enum class Views { class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { + enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { - val selectedView = remember { mutableStateOf(Views.Programmatic) } + var selectedView by remember { mutableStateOf(Views.Programmatic) } + GrossTheme { Scaffold( bottomBar = { BottomAppBar { NavigationBarItem( - selected = false, + selected = selectedView == Views.Programmatic, onClick = { - selectedView.value = Views.Programmatic + selectedView = Views.Programmatic }, icon = { Icon( @@ -50,9 +55,9 @@ class MainActivity : ComponentActivity() { }, ) NavigationBarItem( - selected = false, + selected = selectedView == Views.AssetBased, onClick = { - selectedView.value = Views.AssetBased + selectedView = Views.AssetBased }, icon = { Icon( @@ -70,7 +75,7 @@ class MainActivity : ComponentActivity() { .padding(paddingValues), color = MaterialTheme.colorScheme.background, ) { - when (selectedView.value) { + when (selectedView) { Views.Programmatic -> ProgrammaticOssView() Views.AssetBased -> AssetsOssView() } diff --git a/sample/app/src/main/kotlin/se/premex/gross/OssArtifactView.kt b/sample/app/src/main/kotlin/se/premex/gross/OssArtifactView.kt index 6f4e4ae..57135d5 100644 --- a/sample/app/src/main/kotlin/se/premex/gross/OssArtifactView.kt +++ b/sample/app/src/main/kotlin/se/premex/gross/OssArtifactView.kt @@ -1,13 +1,16 @@ package se.premex.gross import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import io.githhub.usefulness.licensee.android.app.R import se.premex.gross.ui.AssetLicenseeParser import se.premex.gross.ui.ErrorView @@ -15,7 +18,6 @@ import se.premex.gross.ui.LoadingView import se.premex.gross.ui.OssView import se.premex.gross.ui.OssViewState import se.premex.gross.ui.State -import java.io.IOException @Composable fun AssetsOssView() { @@ -23,27 +25,25 @@ fun AssetsOssView() { val licenseParser = remember { AssetLicenseeParser(assetManager) } - val uiState = remember { mutableStateOf(OssViewState()) } + val uiState = remember { mutableStateOf(State.Loading) } - LaunchedEffect(key1 = assetManager) { - try { - uiState.value = OssViewState(viewState = State.Success(data = licenseParser.readFromAssets())) - } catch (ioException: IOException) { - uiState.value = - OssViewState( - viewState = State.Failed( - errorMessage = ioException.localizedMessage ?: "", - ), - ) - } + LaunchedEffect(assetManager) { + uiState.value = runCatching { licenseParser.readFromAssets() }.fold( + onSuccess = { State.Success(data = it) }, + onFailure = { State.Failed(errorMessage = it.localizedMessage.orEmpty()) }, + ) } - when (val state = uiState.value.viewState) { + when (val state = uiState.value) { + State.Loading -> LoadingView(stringResource(id = R.string.loading)) is State.Failed -> ErrorView(stringResource(id = R.string.error), state.errorMessage) - is State.Loading -> LoadingView(stringResource(id = R.string.loading)) is State.Success -> { Column { - Text(text = stringResource(id = R.string.assetBased)) + Text( + text = stringResource(id = R.string.assetBased), + modifier = Modifier + .padding(16.dp), + ) OssView(state.data) } diff --git a/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt b/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt index bf61816..5f1d0c8 100644 --- a/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt +++ b/sample/app/src/main/kotlin/se/premex/gross/OssKotlinCodeView.kt @@ -1,9 +1,12 @@ package se.premex.gross import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp import io.githhub.usefulness.licensee.android.app.R import io.github.usefulness.licensee.LicenseeForAndroid import se.premex.gross.ui.OssView @@ -11,7 +14,11 @@ import se.premex.gross.ui.OssView @Composable fun ProgrammaticOssView() { Column { - Text(text = stringResource(id = R.string.programmatic)) + Text( + text = stringResource(id = R.string.programmatic), + modifier = Modifier + .padding(16.dp), + ) OssView(LicenseeForAndroid.artifacts) } } diff --git a/sample/app/src/main/kotlin/se/premex/gross/ui/theme/Theme.kt b/sample/app/src/main/kotlin/se/premex/gross/ui/theme/Theme.kt index ae5e947..4c601da 100644 --- a/sample/app/src/main/kotlin/se/premex/gross/ui/theme/Theme.kt +++ b/sample/app/src/main/kotlin/se/premex/gross/ui/theme/Theme.kt @@ -1,6 +1,5 @@ package se.premex.gross.ui.theme -import android.app.Activity import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme @@ -9,11 +8,7 @@ import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicLightColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalView -import androidx.core.view.WindowCompat private val DarkColorScheme = darkColorScheme( primary = Purple80, @@ -53,14 +48,6 @@ fun GrossTheme( darkTheme -> DarkColorScheme else -> LightColorScheme } - val view = LocalView.current - if (!view.isInEditMode) { - SideEffect { - val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() - WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme - } - } MaterialTheme( colorScheme = colorScheme, diff --git a/sample/build.gradle b/sample/build.gradle index 49954eb..150d5e6 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -3,6 +3,7 @@ plugins { alias(libs.plugins.starter.application.android) apply false alias(libs.plugins.starter.library.android) apply false alias(libs.plugins.starter.library.kotlin) apply false + id("io.github.usefulness.licensee-for-android") apply false } commonConfig { diff --git a/sample/gradle/libs.versions.toml b/sample/gradle/libs.versions.toml index 52d4650..a7e78d9 100644 --- a/sample/gradle/libs.versions.toml +++ b/sample/gradle/libs.versions.toml @@ -5,7 +5,6 @@ maven-kotlin = "1.9.20" maven-junit = "5.10.1" maven-junit4 = "4.13.2" maven-assertj = "3.24.2" - activity-compose = "1.8.1" androidx-compose-compiler = "1.5.4" androidx-core = "1.12.0" @@ -24,7 +23,7 @@ junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher junit4 = { module = "junit:junit", version.ref = "maven-junit4" } assertj-core = { module = "org.assertj:assertj-core", version.ref = "maven-assertj" } -kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "maven-kotlin-serialization" } +kotlinx-serialization-json-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "maven-kotlin-serialization" } kotlinx-serialization-json-okio = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-okio", version.ref = "maven-kotlin-serialization" } com-squareup-okio = "com.squareup.okio:okio:3.6.0" @@ -66,3 +65,4 @@ starter-library-kotlin = { id = "com.starter.library.kotlin", version.ref = "gra starter-library-android = { id = "com.starter.library.android", version.ref = "gradle-starter" } starter-application-android = { id = "com.starter.application.android", version.ref = "gradle-starter" } app-cash-licensee = "app.cash.licensee:1.8.0" +starter-easylauncher = "com.starter.easylauncher:6.2.0" diff --git a/sample/keys/debug.keystore b/sample/keys/debug.keystore new file mode 100644 index 0000000000000000000000000000000000000000..551b5fe8dbc5a038c2d814b61dec4def20ad5264 GIT binary patch literal 2570 zcma)8X*d*&7M@|qSh5S(GUT(T8QD_El06a`#_qFkV;M_EmYGHxWsfiG5XlxZF_uD@ zFf&a^)+Dkg`FwyGsVpbWFcVKuAG3Ep?<$6*m$7M zP@TV9Zm0@K$i^1QRoam)lmIl5hnR+n1gfWPu&^lbu>c`ZZg!4;Z)5?p0icrXV9!)@ zpf4*3s0`v$QpgoA{aDuDd3X*`>A({V!hnWZ4unxc)=PwoV9;*ORcewOw^WOuLii!K zjrU(W#IckPbV4Lg)4X^$ZQ>|5gWAwuXnF0>oiPW*&?iJZBn-(HBBEtnRl;LaW~zyo z*aG~ArN~(h8_YF)}jAyg8{r0Uo_Y*YBHhjg5{`N3CY^Qy^LtYWKnridXb9x=c3B&e5GJVqkB zH;-IB2%KrQqsrbCo^8(W%4y_L%v^InI$H3B&5>m9prT;F1A)@$`g=MznGBu;lifXm zq@0~jaPWou3=XBX!( zN{HD#P2KkOv#N97#QK@lLllGw5`D8L{?dY<0J0mth6f|1`8zyF_*)MMVZ5c))a%Q- zs*ZZ1v^-Q&6|Gq zwC#Q;ou|=V>6K0?fGeHMo}qgt;llm{os)0)M?0=OBHnEig@ZV42k)Df6uLT%USu+? zw53iVsta;H9}9+!!8^@7PlJ4%%fHS|_ChG8tE-2crVkvyQ1{4GkoUz?eT(tSoF4&) ziB|(q_NamZSPC|Z_B6XrwHf@oia{){Y&;>U`yoYeb6aVm!F$%_LZUBK>{eKR);Es& zsVB_SuQk4Y+L2YaE}K?TYY~|Usl^Bf+01N<{{FJ0tT8_~U6A9;k=^MrHzYnTW_|52 z__BJ<%cx3qQwljz;AfCs_A4@b>424(3}r6=R2F9ko9zTIkw}nq^Q?=(mxkFZTQB&m z-hFG@s3}Ia;e7;3%qAl(bhZSCLM@Cfmf!jE1Sjnvg6&nW(IRFGUHdhEMRFG-fW=WW zJ}XM_!)`#&{jy825DX$E1@Hod0ek?F03;yrB>Mn-0p5UUfIlGkq`C!_`CBdw69Nf1 z1cv%TVA@cqhPH;DwxC zIM=On&8o7llAU({k8z9fc3t8hA7AK37ovx~cnHZD)+^;9&x{!|Y0BTrdI~=PK7c~@fEZ)-*2=;v{Z+Byos)jO0;Z$pcC;seNW7#<1 zsfoz_XZFwSxH;%!td&vyqO0;`13_alWnb%u4iQJeu@AUA`ThBGuh%NBKKk_Qi&Zxe zy#A@FFO4~hat_l*ORTf?^wa?ZY(v{eiYP+J_rX@3NAxH$M=ovXnckU0pR;Om&8beV zpg=~zVBm`KBKI4HbapA9k-WO_?cKPAkUV6SN2PFDS*QvYy8+|7!EwfZ6m@g7II6Dv z49dW%AGpHAJ$u$#oKROSl&`>Kn7_C;;xncLvEdFi_P>N}RoNlY#&?xF!F-P*H=1kE z;bn|c04d>}bZ?p3;{wa7uAwhYKl5JCpus~ogCK>U(%+iu$H3t8@pYydcO!Tb&J)cP z(#x}3CKsILnjfrQ2d&ksY=+OKPP`Le7)kQt>kSI?=0asArV{YjJf4tP`Y?^G0%e%^ zjQFpZL(fB}1;z#>gP*viym=q92rsPpV?UP8edOZ(qHOYIx|s?8*XBy>9DNueG;{r6 zf~+OFTFhsJ(OZ(!gz-8_g^6v*!hVuEZYyzE%HMuAojd^HDbx84Fs zjM%O&yq37SgZH8{)I+W2zkl>_La-d9s1cRD&&5cyvY;TI;(A#1tF4LCO|?CoUNMb-#i*D7^a_A>ORID8>xBOa D?X#`l literal 0 HcmV?d00001 diff --git a/sample/serialization/build.gradle b/sample/serialization/build.gradle index b20328e..09c194a 100644 --- a/sample/serialization/build.gradle +++ b/sample/serialization/build.gradle @@ -42,7 +42,7 @@ tasks.withType(Test).configureEach { } dependencies { - api(libs.kotlinx.serialization.json) + api(libs.kotlinx.serialization.json.core) implementation(libs.kotlinx.serialization.json.okio) api(libs.com.squareup.okio) diff --git a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt index 561c50a..ac2eede 100644 --- a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt +++ b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssView.kt @@ -19,11 +19,9 @@ import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshots.SnapshotStateList import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalUriHandler @@ -36,22 +34,12 @@ import io.github.usefulness.licensee.Artifact @Composable fun OssView(artifacts: List, modifier: Modifier = Modifier) { - val viewData = artifacts.map { artifact -> - val spdxViewLicenses = artifact.spdxLicenses.map { ViewLicense(title = it.name, url = it.url) } - val unknown = artifact.unknownLicenses.map { ViewLicense(title = it.name, url = it.url) } - - val nameOrPackage = ("${artifact.name}\n(${artifact.groupId}:${artifact.artifactId}:${artifact.version})".trim()) - - ViewArtifact( - title = nameOrPackage, - licenses = spdxViewLicenses + unknown, + var visibleDialog by remember { mutableStateOf(value = null) } + visibleDialog?.let { dialog -> + LicenseSelector( + dialogData = dialog, + onDismissRequest = { visibleDialog = null }, ) - }.sortedBy { (nameOrPackage, _) -> nameOrPackage } - - val licenses: SnapshotStateList = remember { mutableStateListOf() } - var alertTitle by remember { mutableStateOf("") } - LicenseSelector(alertTitle, licenses) { - licenses.clear() } LazyColumn( @@ -59,7 +47,7 @@ fun OssView(artifacts: List, modifier: Modifier = Modifier) { horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { - item { + item(key = "header") { Column( modifier = Modifier .fillMaxSize() @@ -75,20 +63,37 @@ fun OssView(artifacts: List, modifier: Modifier = Modifier) { } } - val grouped: Map> = - viewData.groupBy { it.title[0].uppercaseChar().toString() } + val viewData = artifacts.map { artifact -> + val spdxViewLicenses = artifact.spdxLicenses.map { ViewLicense(title = it.name, url = it.url) } + val unknown = artifact.unknownLicenses.map { ViewLicense(title = it.name, url = it.url) } + + val nameOrPackage = ("${artifact.name}\n(${artifact.groupId}:${artifact.artifactId}:${artifact.version})".trim()) + + ViewArtifact( + key = "${artifact.groupId}:${artifact.artifactId}", + title = nameOrPackage, + licenses = spdxViewLicenses + unknown, + ) + } + .sortedBy { (nameOrPackage, _) -> nameOrPackage } + val grouped = viewData.groupBy { it.title[0].uppercaseChar().toString() } grouped.forEach { (title, list) -> stickyHeader { CharacterHeader(title) } - items(list) { artifact -> + items( + items = list, + key = { it.key }, + ) { artifact -> ListItem( headlineContent = { Text(text = artifact.title) }, modifier = Modifier.clickable { - alertTitle = artifact.title - licenses.addAll(artifact.licenses) + visibleDialog = LicensesDialogData( + title = artifact.title, + licenses = artifact.licenses, + ) }, ) } @@ -96,10 +101,17 @@ fun OssView(artifacts: List, modifier: Modifier = Modifier) { } } +private data class LicensesDialogData( + val title: String, + val licenses: List, +) + private data class ViewArtifact( + val key: String, val title: String, val licenses: List, ) + private data class ViewLicense( val title: String, val url: String, @@ -122,50 +134,51 @@ fun CharacterHeader(initial: String, modifier: Modifier = Modifier) { @Composable private fun LicenseSelectorPreview() { Column(Modifier.fillMaxSize()) { - LicenseSelector("Licenses", listOf(ViewLicense("aaa", "http://google.se"))) { - } + LicenseSelector( + dialogData = LicensesDialogData( + title = "Foo Library", + licenses = listOf(ViewLicense(title = "Foo License", url = "http://google.se")), + ), + onDismissRequest = { }, + ) } } @Composable -private fun LicenseSelector(title: String, licenses: List, close: () -> Unit) { +private fun LicenseSelector(dialogData: LicensesDialogData, onDismissRequest: () -> Unit) { val uriHandler = LocalUriHandler.current - if (licenses.isNotEmpty()) { - AlertDialog( - onDismissRequest = { - close() - }, - title = { - Text(text = title) - }, - text = { - Column { - licenses.forEach { license -> - ListItem( - headlineContent = { - Text(text = license.title) - }, - leadingContent = { - Icon( - imageVector = Icons.Filled.Link, - contentDescription = null, - ) - }, - modifier = Modifier.clickable { - uriHandler.openUri(license.url) - }, - ) - } - } - }, - confirmButton = { - TextButton( - onClick = close, - ) { - Text(stringResource(id = R.string.close)) + AlertDialog( + onDismissRequest = onDismissRequest, + title = { + Text(text = dialogData.title) + }, + text = { + Column { + dialogData.licenses.forEach { license -> + ListItem( + headlineContent = { + Text(text = license.title) + }, + leadingContent = { + Icon( + imageVector = Icons.Filled.Link, + contentDescription = null, + ) + }, + modifier = Modifier.clickable { + uriHandler.openUri(license.url) + }, + ) } - }, - ) - } + } + }, + confirmButton = { + TextButton( + onClick = onDismissRequest, + ) { + Text(stringResource(id = R.string.close)) + } + }, + ) } diff --git a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt index f73babd..91403c9 100644 --- a/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt +++ b/sample/ui/src/main/kotlin/se/premex/gross/ui/OssViewModel.kt @@ -2,10 +2,10 @@ package se.premex.gross.ui import io.github.usefulness.licensee.Artifact -sealed class State { - class Loading : State() +sealed class State { + data object Loading : State() data class Success(val data: T) : State() data class Failed(val errorMessage: String) : State() } -data class OssViewState(val viewState: State> = State.Loading()) +typealias OssViewState = State>