--- a/ui/material2/build.gradle.kts	Tue Apr 22 17:48:27 2025 -0400
+++ b/ui/material2/build.gradle.kts	Tue Apr 22 17:56:14 2025 -0400
@@ -19,10 +19,13 @@
  * You should have received a copy of the GNU General Public License
  * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
  */
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
 plugins {
     id("com.android.library")
-    kotlin("android")
+    kotlin("multiplatform")
     alias(libs.plugins.org.jetbrains.kotlin.compose.compiler)
+    alias(libs.plugins.org.jetbrains.compose.multiplatform)
     id("com.geekorum.build.source-license-checker")
     `maven-publish`
 }
@@ -30,6 +33,41 @@
 group = "com.geekorum.aboutoss"
 version = "0.1.0"
 
+kotlin {
+    androidTarget {
+        compilerOptions {
+            jvmTarget.set(JvmTarget.JVM_17)
+        }
+    }
+
+    jvm("desktop")
+
+    listOf(
+        iosX64(),
+        iosArm64(),
+        iosSimulatorArm64(),
+    ).forEach { iosTarget ->
+        iosTarget.binaries.framework {
+            baseName = "aboutoss-core"
+            isStatic = true
+        }
+    }
+
+    sourceSets {
+        commonMain.dependencies {
+            api(project(":ui:common"))
+            implementation(project(":core"))
+            implementation(compose.material)
+            implementation(compose.components.resources)
+        }
+
+        androidMain.dependencies {
+            api(libs.androidx.activity)
+        }
+    }
+}
+
+
 android {
     namespace = "com.geekorum.aboutoss.ui.material"
     compileSdk = 35
@@ -55,11 +93,8 @@
         }
     }
     compileOptions {
-        sourceCompatibility = JavaVersion.VERSION_1_8
-        targetCompatibility = JavaVersion.VERSION_1_8
-    }
-    kotlinOptions {
-        jvmTarget = "1.8"
+        sourceCompatibility = JavaVersion.VERSION_17
+        targetCompatibility = JavaVersion.VERSION_17
     }
 
     buildFeatures {
@@ -75,10 +110,7 @@
 }
 
 dependencies {
-    api(project(":ui:common"))
     implementation(platform(libs.androidx.compose.bom))
-    implementation(libs.androidx.compose.material)
-    implementation(libs.androidx.compose.material.icons.core)
     implementation(libs.androidx.activity.compose)
     implementation(libs.androidx.navigation.compose)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/material2/src/androidMain/AndroidManifest.xml	Tue Apr 22 17:56:14 2025 -0400
@@ -0,0 +1,34 @@
+<!--
+
+    AboutOss is an utility library to retrieve and display
+    opensource licenses in Android applications.
+
+    Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
+
+    This file is part of AboutOss.
+
+    AboutOss is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    AboutOss is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
+
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+    <application>
+        <activity android:name=".OpenSourceLicensesActivity"
+            android:theme="@android:style/Theme.Material.Light.NoActionBar"
+            android:label="@string/title_oss_licenses"
+            android:exported="false"
+            />
+
+    </application>
+
+</manifest>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/material2/src/androidMain/kotlin/OpenSourceLicensesActivity.kt	Tue Apr 22 17:56:14 2025 -0400
@@ -0,0 +1,115 @@
+/*
+ * AboutOss is an utility library to retrieve and display
+ * opensource licenses in Android applications.
+ *
+ * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
+ *
+ * This file is part of AboutOss.
+ *
+ * AboutOss is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AboutOss is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.aboutoss.ui.material
+
+import android.net.Uri
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.activity.viewModels
+import androidx.compose.material.MaterialTheme
+import androidx.compose.runtime.Composable
+import androidx.navigation.compose.NavHost
+import androidx.navigation.compose.composable
+import androidx.navigation.compose.rememberNavController
+import com.geekorum.aboutoss.core.gms.GmsLicenseInfoRepository
+import com.geekorum.aboutoss.ui.common.BaseOpensourceLicenseActivity
+import com.geekorum.aboutoss.ui.common.Factory
+import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
+import com.geekorum.aboutoss.ui.material.OpenSourceLicensesActivity.Companion.themeProvider
+import kotlinx.coroutines.Dispatchers
+
+/**
+ * Activity to display opensource license information
+ *
+ * This activity use Material compose to create the UI.
+ * You can specify the Material theme to use by setting [themeProvider]
+ * before launching the activity
+ */
+open class OpenSourceLicensesActivity : BaseOpensourceLicenseActivity() {
+    override val viewModel: OpenSourceLicensesViewModel by viewModels(
+        factoryProducer = {
+            val gmsLicenseInfoRepository = GmsLicenseInfoRepository(
+                appContext = applicationContext,
+                mainCoroutineDispatcher = Dispatchers.Main,
+                ioCoroutineDispatcher = Dispatchers.IO,
+            )
+            OpenSourceLicensesViewModel.Factory(gmsLicenseInfoRepository)
+        }
+    )
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContent {
+            themeProvider {
+                DependencyNavHost(
+                    openSourceLicensesViewModel = viewModel,
+                    navigateUp = {
+                        if (!onNavigateUp()) {
+                            finish()
+                        }
+                    }
+                )
+            }
+        }
+    }
+
+    companion object {
+        /**
+         * The composable Theme function to set the theme of the UI in [OpenSourceLicensesActivity]
+         * Default to base material theme [MaterialTheme]
+         */
+        var themeProvider: @Composable (@Composable () -> Unit) -> Unit = { content ->
+            MaterialTheme(content = content)
+        }
+    }
+}
+
+
+@Composable
+fun DependencyNavHost(
+    openSourceLicensesViewModel: OpenSourceLicensesViewModel,
+    navigateUp: () -> Unit
+) {
+    val navController = rememberNavController()
+    NavHost(navController, startDestination = "dependencies") {
+        composable("dependencies") {
+            OpenSourceDependenciesListScreen(
+                viewModel = openSourceLicensesViewModel,
+                onDependencyClick = {
+                    navController.navigate("dependency_license/${Uri.encode(it)}")
+                },
+                onUpClick = navigateUp
+            )
+        }
+        composable("dependency_license/{dependency}") {
+            val dependency = requireNotNull(it.arguments?.getString("dependency"))
+            OpenSourceLicenseScreen(
+                viewModel = openSourceLicensesViewModel,
+                dependency = dependency,
+                onUpClick = {
+                    navController.popBackStack()
+                },
+            )
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/material2/src/commonMain/kotlin/com/geekorum/aboutoss/ui/material/OpenSourceDependenciesListScreen.kt	Tue Apr 22 17:56:14 2025 -0400
@@ -0,0 +1,132 @@
+/*
+ * AboutOss is an utility library to retrieve and display
+ * opensource licenses in Android applications.
+ *
+ * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
+ *
+ * This file is part of AboutOss.
+ *
+ * AboutOss is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AboutOss is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.aboutoss.ui.material
+
+import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.lazy.rememberLazyListState
+import androidx.compose.material.Divider
+import androidx.compose.material.ExperimentalMaterialApi
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.ListItem
+import androidx.compose.material.Scaffold
+import androidx.compose.material.Text
+import androidx.compose.material.TopAppBar
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import com.geekorum.aboutoss.common.generated.resources.title_oss_licenses
+import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
+import org.jetbrains.compose.resources.stringResource
+import com.geekorum.aboutoss.common.generated.resources.Res as CommonRes
+
+/**
+ * Display the list of dependencies used in the application
+ *
+ * @param viewModel the [OpenSourceLicensesViewModel] to use
+ * @param onDependencyClick lambda to execute on click on one dependency item
+ * @param onUpClick lambda to execute on click on the up arrow
+ */
+@Composable
+fun OpenSourceDependenciesListScreen(
+    viewModel: OpenSourceLicensesViewModel,
+    onDependencyClick: (String) -> Unit,
+    onUpClick: () -> Unit
+) {
+    val dependencies by viewModel.dependenciesList.collectAsState(initial = emptyList())
+    OpenSourceDependenciesListScreen(
+        dependencies = dependencies,
+        onDependencyClick = onDependencyClick,
+        onUpClick = onUpClick
+    )
+}
+
+/**
+ * Display the list of dependencies used in the application
+ *
+ * @param dependencies the list of dependencies
+ * @param onDependencyClick lambda to execute on click on one dependency item
+ * @param onUpClick lambda to execute on click on the up arrow
+ */
+@OptIn(ExperimentalMaterialApi::class)
+@Composable
+fun OpenSourceDependenciesListScreen(
+    dependencies: List<String>,
+    onDependencyClick: (String) -> Unit,
+    onUpClick: () -> Unit
+) {
+    val lazyListState = rememberLazyListState()
+    val hasScrolled by remember {
+        derivedStateOf {
+            lazyListState.firstVisibleItemIndex  != 0 || lazyListState.firstVisibleItemScrollOffset > 0
+        }
+    }
+    val topBarElevation by animateDpAsState(
+        if (hasScrolled) 4.dp else 0.dp,
+        label = "topBarElevation"
+    )
+    Scaffold(topBar = {
+        TopAppBar(title = { Text(stringResource(CommonRes.string.title_oss_licenses)) },
+            navigationIcon = {
+                IconButton(onClick = onUpClick) {
+                    Icon(
+                        Icons.AutoMirrored.Filled.ArrowBack,
+                        contentDescription = null
+                    )
+                }
+            },
+            elevation = topBarElevation
+        )
+    }) {
+        LazyColumn(Modifier.fillMaxSize(), state = lazyListState, contentPadding = it) {
+            items(dependencies) {
+                Column {
+                    ListItem(
+                        Modifier
+                            .height(64.dp)
+                            .clickable(onClick = { onDependencyClick(it) })
+                    ) {
+                        Text(
+                            it, modifier = Modifier.padding(horizontal = 16.dp),
+                            overflow = TextOverflow.Ellipsis, maxLines = 1
+                        )
+                    }
+                    Divider(Modifier.padding(horizontal = 16.dp))
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ui/material2/src/commonMain/kotlin/com/geekorum/aboutoss/ui/material/OpenSourceLicenseScreen.kt	Tue Apr 22 17:56:14 2025 -0400
@@ -0,0 +1,194 @@
+/*
+ * AboutOss is an utility library to retrieve and display
+ * opensource licenses in Android applications.
+ *
+ * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
+ *
+ * This file is part of AboutOss.
+ *
+ * AboutOss is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * AboutOss is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.aboutoss.ui.material
+
+import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.layout.ExperimentalLayoutApi
+import androidx.compose.foundation.layout.consumeWindowInsets
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Scaffold
+import androidx.compose.material.Text
+import androidx.compose.material.TopAppBar
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.filled.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.ExperimentalTextApi
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.UrlAnnotation
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.style.TextDecoration
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.text.withAnnotation
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.unit.dp
+import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
+
+/**
+ * Display the opensource license of a dependency
+ *
+ * @param viewModel the [OpenSourceLicensesViewModel] to use
+ * @param dependency the dependency
+ * @param onUpClick lambda to execute on click on the up arrow
+ */
+@Composable
+fun OpenSourceLicenseScreen(
+    viewModel: OpenSourceLicensesViewModel,
+    dependency: String,
+    onUpClick: () -> Unit,
+) {
+    val license by viewModel.getLicenseDependency(dependency).collectAsState("")
+    OpenSourceLicenseScreen(
+        dependency = dependency,
+        license = license,
+        onUpClick = onUpClick,
+        onUrlClick = {
+            viewModel.openLinkInBrowser(it)
+        },
+        onUrlsFound = {
+            viewModel.mayLaunchUrl(*it.toTypedArray())
+        }
+    )
+}
+
+/**
+ * Display the opensource license of a dependency
+ *
+ * @param dependency the dependency
+ * @param license the opensource license text
+ * @param onUpClick lambda to execute on click on the up arrow
+ * @param onUrlClick lambda to execute on click on a url
+ * @param onUrlsFound lambda to execute when all urls in the license have been found
+ */
+@OptIn(ExperimentalLayoutApi::class, ExperimentalTextApi::class)
+@Composable
+fun OpenSourceLicenseScreen(
+    dependency: String,
+    license: String,
+    onUpClick: () -> Unit,
+    onUrlClick: (String) -> Unit,
+    onUrlsFound: (List<String>) -> Unit,
+) {
+    val linkifiedLicense = linkifyText(text = license)
+    LaunchedEffect(linkifiedLicense) {
+        val uris =
+            linkifiedLicense.getUrlAnnotations(0, linkifiedLicense.length).map { it.item.url }
+        onUrlsFound(uris)
+    }
+
+    val scrollState = rememberScrollState()
+    val hasScrolled by remember {
+        derivedStateOf { scrollState.value > 0 }
+    }
+    val topBarElevation by animateDpAsState(
+        if (hasScrolled) 4.dp else 0.dp,
+        label = "topBarElevation"
+    )
+    Scaffold(topBar = {
+        TopAppBar(title = { Text(dependency, overflow = TextOverflow.Ellipsis, maxLines = 1) },
+            navigationIcon = {
+                IconButton(onClick = onUpClick) {
+                    Icon(
+                        Icons.AutoMirrored.Filled.ArrowBack,
+                        contentDescription = null
+                    )
+                }
+            },
+            elevation = topBarElevation
+        )
+    }) { paddingValues ->
+        val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
+        val pressIndicator = Modifier.pointerInput(layoutResult, linkifiedLicense) {
+            detectTapGestures { pos ->
+                layoutResult.value?.let { layoutResult ->
+                    val posWithScroll = pos.copy(y = pos.y + scrollState.value)
+                    val offset = layoutResult.getOffsetForPosition(posWithScroll)
+                    linkifiedLicense.getUrlAnnotations(start = offset, end = offset)
+                        .firstOrNull()?.let { annotation ->
+                            onUrlClick(annotation.item.url)
+                        }
+                }
+            }
+        }
+
+        Text(linkifiedLicense,
+            modifier = Modifier
+                .padding(paddingValues)
+                .consumeWindowInsets(paddingValues)
+                .padding(horizontal = 16.dp)
+                .fillMaxSize()
+                .then(pressIndicator)
+                .verticalScroll(scrollState),
+            onTextLayout = {
+                layoutResult.value = it
+            }
+        )
+    }
+}
+
+/**
+ * https://regexr.com/37i6s
+ */
+private val urlRegexp = """https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)""".toRegex()
+
+@OptIn(ExperimentalTextApi::class)
+@Composable
+private fun linkifyText(text: String): AnnotatedString {
+    val style = SpanStyle(
+        color = MaterialTheme.colors.secondary,
+        textDecoration = TextDecoration.Underline
+    )
+    return remember(text, style) {
+        buildAnnotatedString {
+            var currentIdx = 0
+            for (match in urlRegexp.findAll(text)) {
+                if (currentIdx < match.range.first) {
+                    append(text.substring(currentIdx, match.range.first))
+                }
+                val url = text.substring(match.range)
+                withAnnotation(UrlAnnotation(url)) {
+                    withStyle(style) {
+                        append(url)
+                    }
+                }
+                currentIdx = match.range.last + 1
+            }
+            append(text.substring(currentIdx))
+        }
+    }
+}
--- a/ui/material2/src/main/AndroidManifest.xml	Tue Apr 22 17:48:27 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-<!--
-
-    AboutOss is an utility library to retrieve and display
-    opensource licenses in Android applications.
-
-    Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
-
-    This file is part of AboutOss.
-
-    AboutOss is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    AboutOss is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
-
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
-    <application>
-        <activity android:name=".OpenSourceLicensesActivity"
-            android:theme="@style/Theme.AppCompat.NoActionBar"
-            android:label="@string/title_oss_licenses"
-            android:exported="false"
-            />
-
-    </application>
-
-</manifest>
\ No newline at end of file
--- a/ui/material2/src/main/java/com/geekorum/aboutoss/ui/material/OpenSourceDependenciesListScreen.kt	Tue Apr 22 17:48:27 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * AboutOss is an utility library to retrieve and display
- * opensource licenses in Android applications.
- *
- * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
- *
- * This file is part of AboutOss.
- *
- * AboutOss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AboutOss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.aboutoss.ui.material
-
-import androidx.compose.animation.core.animateDpAsState
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.foundation.lazy.rememberLazyListState
-import androidx.compose.material.Divider
-import androidx.compose.material.ExperimentalMaterialApi
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.ListItem
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Text
-import androidx.compose.material.TopAppBar
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.derivedStateOf
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.dp
-import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
-import com.geekorum.aboutoss.ui.common.R as commonR
-
-/**
- * Display the list of dependencies used in the application
- *
- * @param viewModel the [OpenSourceLicensesViewModel] to use
- * @param onDependencyClick lambda to execute on click on one dependency item
- * @param onUpClick lambda to execute on click on the up arrow
- */
-@Composable
-fun OpenSourceDependenciesListScreen(
-    viewModel: OpenSourceLicensesViewModel,
-    onDependencyClick: (String) -> Unit,
-    onUpClick: () -> Unit
-) {
-    val dependencies by viewModel.dependenciesList.collectAsState(initial = emptyList())
-    OpenSourceDependenciesListScreen(
-        dependencies = dependencies,
-        onDependencyClick = onDependencyClick,
-        onUpClick = onUpClick
-    )
-}
-
-/**
- * Display the list of dependencies used in the application
- *
- * @param dependencies the list of dependencies
- * @param onDependencyClick lambda to execute on click on one dependency item
- * @param onUpClick lambda to execute on click on the up arrow
- */
-@OptIn(ExperimentalMaterialApi::class)
-@Composable
-fun OpenSourceDependenciesListScreen(
-    dependencies: List<String>,
-    onDependencyClick: (String) -> Unit,
-    onUpClick: () -> Unit
-) {
-    val lazyListState = rememberLazyListState()
-    val hasScrolled by remember {
-        derivedStateOf {
-            lazyListState.firstVisibleItemIndex  != 0 || lazyListState.firstVisibleItemScrollOffset > 0
-        }
-    }
-    val topBarElevation by animateDpAsState(
-        if (hasScrolled) 4.dp else 0.dp,
-        label = "topBarElevation"
-    )
-    Scaffold(topBar = {
-        TopAppBar(title = { Text(stringResource(commonR.string.title_oss_licenses)) },
-            navigationIcon = {
-                IconButton(onClick = onUpClick) {
-                    Icon(
-                        Icons.Default.ArrowBack,
-                        contentDescription = null
-                    )
-                }
-            },
-            elevation = topBarElevation
-        )
-    }) {
-        LazyColumn(Modifier.fillMaxSize(), state = lazyListState, contentPadding = it) {
-            items(dependencies) {
-                Column {
-                    ListItem(
-                        Modifier
-                            .height(64.dp)
-                            .clickable(onClick = { onDependencyClick(it) })
-                    ) {
-                        Text(
-                            it, modifier = Modifier.padding(horizontal = 16.dp),
-                            overflow = TextOverflow.Ellipsis, maxLines = 1
-                        )
-                    }
-                    Divider(Modifier.padding(horizontal = 16.dp))
-                }
-            }
-        }
-    }
-}
--- a/ui/material2/src/main/java/com/geekorum/aboutoss/ui/material/OpenSourceLicenseScreen.kt	Tue Apr 22 17:48:27 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * AboutOss is an utility library to retrieve and display
- * opensource licenses in Android applications.
- *
- * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
- *
- * This file is part of AboutOss.
- *
- * AboutOss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AboutOss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.aboutoss.ui.material
-
-import androidx.compose.animation.core.animateDpAsState
-import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.verticalScroll
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.MaterialTheme
-import androidx.compose.material.Scaffold
-import androidx.compose.material.Text
-import androidx.compose.material.TopAppBar
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.ArrowBack
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
-import androidx.compose.runtime.collectAsState
-import androidx.compose.runtime.derivedStateOf
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.input.pointer.pointerInput
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.ExperimentalTextApi
-import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.TextLayoutResult
-import androidx.compose.ui.text.UrlAnnotation
-import androidx.compose.ui.text.buildAnnotatedString
-import androidx.compose.ui.text.style.TextDecoration
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.text.withAnnotation
-import androidx.compose.ui.text.withStyle
-import androidx.compose.ui.unit.dp
-import androidx.core.net.toUri
-import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
-
-/**
- * Display the opensource license of a dependency
- *
- * @param viewModel the [OpenSourceLicensesViewModel] to use
- * @param dependency the dependency
- * @param onUpClick lambda to execute on click on the up arrow
- */
-@Composable
-fun OpenSourceLicenseScreen(
-    viewModel: OpenSourceLicensesViewModel,
-    dependency: String,
-    onUpClick: () -> Unit,
-) {
-    val context = LocalContext.current
-    val license by viewModel.getLicenseDependency(dependency).collectAsState("")
-    OpenSourceLicenseScreen(
-        dependency = dependency,
-        license = license,
-        onUpClick = onUpClick,
-        onUrlClick = {
-            viewModel.openLinkInBrowser(context, it)
-        },
-        onUrlsFound = {
-            val uris = it.map { uri -> uri.toUri() }
-            viewModel.mayLaunchUrl(*uris.toTypedArray())
-        }
-    )
-}
-
-/**
- * Display the opensource license of a dependency
- *
- * @param dependency the dependency
- * @param license the opensource license text
- * @param onUpClick lambda to execute on click on the up arrow
- * @param onUrlClick lambda to execute on click on a url
- * @param onUrlsFound lambda to execute when all urls in the license have been found
- */
-@OptIn(ExperimentalLayoutApi::class, ExperimentalTextApi::class)
-@Composable
-fun OpenSourceLicenseScreen(
-    dependency: String,
-    license: String,
-    onUpClick: () -> Unit,
-    onUrlClick: (String) -> Unit,
-    onUrlsFound: (List<String>) -> Unit,
-) {
-    val linkifiedLicense = linkifyText(text = license)
-    LaunchedEffect(linkifiedLicense) {
-        val uris =
-            linkifiedLicense.getUrlAnnotations(0, linkifiedLicense.length).map { it.item.url }
-        onUrlsFound(uris)
-    }
-
-    val scrollState = rememberScrollState()
-    val hasScrolled by remember {
-        derivedStateOf { scrollState.value > 0 }
-    }
-    val topBarElevation by animateDpAsState(
-        if (hasScrolled) 4.dp else 0.dp,
-        label = "topBarElevation"
-    )
-    Scaffold(topBar = {
-        TopAppBar(title = { Text(dependency, overflow = TextOverflow.Ellipsis, maxLines = 1) },
-            navigationIcon = {
-                IconButton(onClick = onUpClick) {
-                    Icon(
-                        Icons.Default.ArrowBack,
-                        contentDescription = null
-                    )
-                }
-            },
-            elevation = topBarElevation
-        )
-    }) { paddingValues ->
-        val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
-        val pressIndicator = Modifier.pointerInput(layoutResult, linkifiedLicense) {
-            detectTapGestures { pos ->
-                layoutResult.value?.let { layoutResult ->
-                    val posWithScroll = pos.copy(y = pos.y + scrollState.value)
-                    val offset = layoutResult.getOffsetForPosition(posWithScroll)
-                    linkifiedLicense.getUrlAnnotations(start = offset, end = offset)
-                        .firstOrNull()?.let { annotation ->
-                            onUrlClick(annotation.item.url)
-                        }
-                }
-            }
-        }
-
-        Text(linkifiedLicense,
-            modifier = Modifier
-                .padding(paddingValues)
-                .consumeWindowInsets(paddingValues)
-                .padding(horizontal = 16.dp)
-                .fillMaxSize()
-                .then(pressIndicator)
-                .verticalScroll(scrollState),
-            onTextLayout = {
-                layoutResult.value = it
-            }
-        )
-    }
-}
-
-/**
- * https://regexr.com/37i6s
- */
-private val urlRegexp = """https?://(www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,4}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)""".toRegex()
-
-@OptIn(ExperimentalTextApi::class)
-@Composable
-private fun linkifyText(text: String): AnnotatedString {
-    val style = SpanStyle(
-        color = MaterialTheme.colors.secondary,
-        textDecoration = TextDecoration.Underline
-    )
-    return remember(text, style) {
-        buildAnnotatedString {
-            var currentIdx = 0
-            for (match in urlRegexp.findAll(text)) {
-                if (currentIdx < match.range.first) {
-                    append(text.substring(currentIdx, match.range.first))
-                }
-                val url = text.substring(match.range)
-                withAnnotation(UrlAnnotation(url)) {
-                    withStyle(style) {
-                        append(url)
-                    }
-                }
-                currentIdx = match.range.last + 1
-            }
-            append(text.substring(currentIdx))
-        }
-    }
-}
--- a/ui/material2/src/main/java/com/geekorum/aboutoss/ui/material/OpenSourceLicensesActivity.kt	Tue Apr 22 17:48:27 2025 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * AboutOss is an utility library to retrieve and display
- * opensource licenses in Android applications.
- *
- * Copyright (C) 2023-2025 by Frederic-Charles Barthelery.
- *
- * This file is part of AboutOss.
- *
- * AboutOss is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AboutOss is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with AboutOss.  If not, see <http://www.gnu.org/licenses/>.
- */
-package com.geekorum.aboutoss.ui.material
-
-import android.net.Uri
-import android.os.Bundle
-import androidx.activity.compose.setContent
-import androidx.compose.material.MaterialTheme
-import androidx.compose.runtime.Composable
-import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
-import androidx.navigation.compose.rememberNavController
-import com.geekorum.aboutoss.ui.common.BaseOpensourceLicenseActivity
-import com.geekorum.aboutoss.ui.common.OpenSourceLicensesViewModel
-
-/**
- * Activity to display opensource license information
- *
- * This activity use Material compose to create the UI.
- * You can specify the Material theme to use by setting [themeProvider]
- * before launching the activity
- */
-open class OpenSourceLicensesActivity : BaseOpensourceLicenseActivity() {
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        setContent {
-            themeProvider {
-                DependencyNavHost(
-                    openSourceLicensesViewModel = viewModel,
-                    navigateUp = {
-                        if (!onNavigateUp()) {
-                            finish()
-                        }
-                    }
-                )
-            }
-        }
-    }
-
-    companion object {
-        /**
-         * The composable Theme function to set the theme of the UI in [OpenSourceLicensesActivity]
-         * Default to base material theme [MaterialTheme]
-         */
-        var themeProvider: @Composable (@Composable () -> Unit) -> Unit = { content ->
-            MaterialTheme(content = content)
-        }
-    }
-}
-
-
-@Composable
-fun DependencyNavHost(
-    openSourceLicensesViewModel: OpenSourceLicensesViewModel,
-    navigateUp: () -> Unit
-) {
-    val navController = rememberNavController()
-    NavHost(navController, startDestination = "dependencies") {
-        composable("dependencies") {
-            OpenSourceDependenciesListScreen(
-                viewModel = openSourceLicensesViewModel,
-                onDependencyClick = {
-                    navController.navigate("dependency_license/${Uri.encode(it)}")
-                },
-                onUpClick = navigateUp
-            )
-        }
-        composable("dependency_license/{dependency}") {
-            val dependency = requireNotNull(it.arguments?.getString("dependency"))
-            OpenSourceLicenseScreen(
-                viewModel = openSourceLicensesViewModel,
-                dependency = dependency,
-                onUpClick = {
-                    navController.popBackStack()
-                },
-            )
-        }
-    }
-}
-