AboutLibraries: display libraries

This commit is contained in:
Pierre-Yves Nicolas
2025-07-08 20:57:15 +02:00
parent d8b0b0d0df
commit 7f34c395a3
7 changed files with 103 additions and 16 deletions

View File

@@ -92,6 +92,7 @@ dependencies {
implementation(libs.pdfbox)
implementation(libs.icons.extended)
implementation(libs.zoomable)
implementation(libs.aboutlibraries.compose.m3)
testImplementation(libs.junit)
testImplementation(libs.assertj)

View File

@@ -41,6 +41,7 @@ import org.mydomain.myscan.ui.theme.MyScanTheme
import org.mydomain.myscan.view.AboutScreen
import org.mydomain.myscan.view.CameraScreen
import org.mydomain.myscan.view.DocumentScreen
import org.mydomain.myscan.view.LibrariesScreen
import org.opencv.android.OpenCVLoader
import java.io.File
@@ -62,6 +63,7 @@ class MainActivity : ComponentActivity() {
toCameraScreen = { viewModel.navigateTo(Screen.Camera) },
toDocumentScreen = { viewModel.navigateTo(Screen.Document()) },
toAboutScreen = { viewModel.navigateTo(Screen.About) },
toLibrariesScreen = { viewModel.navigateTo(Screen.Libraries) },
back = { viewModel.navigateBack() }
)
when (val screen = currentScreen) {
@@ -95,7 +97,10 @@ class MainActivity : ComponentActivity() {
)
}
is Screen.About -> {
AboutScreen(onBack = navigation.back)
AboutScreen(onBack = navigation.back, onViewLibraries = navigation.toLibrariesScreen)
}
is Screen.Libraries -> {
LibrariesScreen(onBack = navigation.back)
}
}
}

View File

@@ -18,11 +18,13 @@ sealed class Screen {
object Camera : Screen()
data class Document(val initialPage: Int = 0) : Screen()
object About : Screen()
object Libraries : Screen()
}
data class Navigation(
val toCameraScreen: () -> Unit,
val toDocumentScreen: () -> Unit,
val toAboutScreen: () -> Unit,
val toLibrariesScreen: () -> Unit,
val back: () -> Unit,
)

View File

@@ -57,8 +57,8 @@ import org.mydomain.myscan.ui.theme.MyScanTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AboutScreen(onBack: () -> Unit) {
val showLicenceDialog = rememberSaveable { mutableStateOf(false) }
fun AboutScreen(onBack: () -> Unit, onViewLibraries: () -> Unit) {
val showLicenseDialog = rememberSaveable { mutableStateOf(false) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
Scaffold(
topBar = {
@@ -72,15 +72,19 @@ fun AboutScreen(onBack: () -> Unit) {
)
}
) { paddingValues ->
AboutContent(Modifier.padding(paddingValues), showLicenceDialog)
AboutContent(modifier = Modifier.padding(paddingValues), showLicenseDialog, onViewLibraries)
}
if (showLicenceDialog.value) {
LicenseBottomSheet(sheetState, onDismiss = { showLicenceDialog.value = false })
if (showLicenseDialog.value) {
LicenseBottomSheet(sheetState, onDismiss = { showLicenseDialog.value = false })
}
}
@Composable
fun AboutContent(modifier: Modifier = Modifier, showLicenceDialog: MutableState<Boolean>) {
fun AboutContent(
modifier: Modifier = Modifier,
showLicenseDialog: MutableState<Boolean>,
onViewLibraries: () -> Unit,
) {
Column(
modifier = modifier
.fillMaxSize()
@@ -104,7 +108,7 @@ fun AboutContent(modifier: Modifier = Modifier, showLicenceDialog: MutableState<
Text(
"Version",
style = MaterialTheme.typography.titleSmall
style = MaterialTheme.typography.titleMedium
)
Text(BuildConfig.VERSION_NAME)
@@ -112,7 +116,7 @@ fun AboutContent(modifier: Modifier = Modifier, showLicenceDialog: MutableState<
Text(
"License",
style = MaterialTheme.typography.titleSmall
style = MaterialTheme.typography.titleMedium
)
Text(
"This application is licensed under the GNU General Public License v3.0.",
@@ -121,19 +125,26 @@ fun AboutContent(modifier: Modifier = Modifier, showLicenceDialog: MutableState<
Text(
text = "View the full license",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.clickable() { showLicenceDialog.value = true },
modifier = Modifier.clickable { showLicenseDialog.value = true },
color = MaterialTheme.colorScheme.primary
)
Spacer(Modifier.height(16.dp))
Text(
"This application is based on the following open-source libraries",
style = MaterialTheme.typography.titleSmall
"Libraries",
style = MaterialTheme.typography.titleMedium
)
Text(
"• CameraX\n• Jetpack Compose\n• LiteRT\n• OpenCV\n• PDFBox",
"This application uses several open-source libraries, including:\n" +
"• CameraX\n• Jetpack Compose\n• LiteRT\n• OpenCV\n• PDFBox",
style = MaterialTheme.typography.bodyMedium)
Text(
text = "View full list",
style = MaterialTheme.typography.bodyMedium,
modifier = Modifier.clickable(onClick = onViewLibraries),
color = MaterialTheme.colorScheme.primary
)
Spacer(Modifier.height(32.dp))
}
@@ -194,11 +205,10 @@ fun LicenseBottomSheet(
}
}
@Preview
@Composable
fun AboutScreenPreview() {
MyScanTheme {
AboutScreen(onBack = {})
AboutScreen(onBack = {}, onViewLibraries = {})
}
}

View File

@@ -284,7 +284,8 @@ fun DocumentScreenPreview() {
BitmapFactory.decodeStream(input)
}
},
navigation = Navigation({}, {}, {}, {}),
navigation = Navigation(
{}, {}, {}, {}, {}),
pdfActions = PdfGenerationActions(
{}, {}, {},
MutableStateFlow(PdfGenerationUiState()),

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2025 Pierre-Yves Nicolas
*
* This program 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.
* This program 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
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.mydomain.myscan.view
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults
import com.mikepenz.aboutlibraries.ui.compose.android.rememberLibraries
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import org.mydomain.myscan.R
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LibrariesScreen(onBack: () -> Unit) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("Open-source libraries") },
navigationIcon = {
IconButton(onClick = onBack) {
Icon(Icons.AutoMirrored.Default.ArrowBack, contentDescription = "Back")
}
}
)
}
) { padding ->
Surface(modifier = Modifier
.fillMaxSize()
.padding(padding)
) {
val librariesState by rememberLibraries(R.raw.aboutlibraries)
LibrariesContainer(
libraries = librariesState,
textStyles = LibraryDefaults.libraryTextStyles(
nameTextStyle = MaterialTheme.typography.titleMedium,
licensesTextStyle = MaterialTheme.typography.labelSmall
),
)
}
}
}

View File

@@ -46,6 +46,7 @@ litert-metadata = { group = "com.google.ai.edge.litert", name = "litert-metadata
opencv = { group="org.opencv", name="opencv", version.ref = "opencv" }
pdfbox = { group = "com.tom-roush", name = "pdfbox-android", version.ref = "pdfbox" }
zoomable = { group = "net.engawapg.lib", name = "zoomable", version.ref = "zoomable" }
aboutlibraries-compose-m3 = { module = "com.mikepenz:aboutlibraries-compose-m3", version.ref = "aboutLibraries" }
assertj = { group="org.assertj", name="assertj-core", version.ref = "assertj" }