Skip to content

Commit 4758244

Browse files
Use AboutLibraries to display library information
1 parent 6d05af4 commit 4758244

7 files changed

Lines changed: 90 additions & 270 deletions

File tree

app/build.gradle

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ plugins {
99
id "kotlin-parcelize"
1010
id "checkstyle"
1111
id "org.sonarqube" version "4.0.0.2929"
12+
id "org.jetbrains.kotlin.plugin.compose" version "${kotlin_version}"
13+
id 'com.mikepenz.aboutlibraries.plugin'
1214
}
1315

1416
android {
@@ -104,10 +106,6 @@ android {
104106
'META-INF/COPYRIGHT']
105107
}
106108
}
107-
108-
composeOptions {
109-
kotlinCompilerExtensionVersion = "1.5.14"
110-
}
111109
}
112110

113111
ext {
@@ -293,6 +291,9 @@ dependencies {
293291
implementation 'androidx.compose.ui:ui-text:1.7.0-beta05' // Needed for parsing HTML to AnnotatedString
294292
implementation 'com.github.nanihadesuka:LazyColumnScrollbar:2.2.0'
295293

294+
// Library loading for About screen
295+
implementation "com.mikepenz:aboutlibraries-compose-m3:$about_libs"
296+
296297
/** Debugging **/
297298
// Memory leak detection
298299
debugImplementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"

app/src/main/java/org/schabi/newpipe/ui/components/about/AboutClasses.kt

Lines changed: 0 additions & 28 deletions
This file was deleted.

app/src/main/java/org/schabi/newpipe/ui/components/about/AboutTab.kt

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
package org.schabi.newpipe.ui.components.about
22

3+
import androidx.annotation.StringRes
34
import androidx.compose.foundation.Image
5+
import androidx.compose.foundation.layout.Arrangement
46
import androidx.compose.foundation.layout.Column
57
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.padding
69
import androidx.compose.foundation.layout.wrapContentSize
710
import androidx.compose.foundation.layout.wrapContentWidth
11+
import androidx.compose.foundation.rememberScrollState
12+
import androidx.compose.foundation.verticalScroll
813
import androidx.compose.material3.MaterialTheme
914
import androidx.compose.material3.Text
1015
import androidx.compose.material3.TextButton
@@ -15,6 +20,8 @@ import androidx.compose.ui.Modifier
1520
import androidx.compose.ui.platform.LocalContext
1621
import androidx.compose.ui.res.painterResource
1722
import androidx.compose.ui.res.stringResource
23+
import androidx.compose.ui.unit.dp
24+
import my.nanihadesuka.compose.ColumnScrollbar
1825
import org.schabi.newpipe.BuildConfig
1926
import org.schabi.newpipe.R
2027
import org.schabi.newpipe.util.external_communication.ShareUtils
@@ -39,30 +46,49 @@ private val ABOUT_ITEMS = listOf(
3946
)
4047
)
4148

49+
private class AboutData(
50+
@StringRes val title: Int,
51+
@StringRes val description: Int,
52+
@StringRes val buttonText: Int,
53+
@StringRes val url: Int
54+
)
55+
4256
@Composable
4357
@NonRestartableComposable
4458
fun AboutTab() {
45-
Column(
46-
modifier = Modifier
47-
.fillMaxWidth()
48-
.wrapContentSize(Alignment.Center),
49-
horizontalAlignment = Alignment.CenterHorizontally
50-
) {
51-
Image(
52-
painter = painterResource(R.drawable.icon),
53-
contentDescription = stringResource(R.string.app_name)
54-
)
55-
Text(
56-
style = MaterialTheme.typography.titleLarge,
57-
text = stringResource(R.string.app_name)
58-
)
59-
Text(text = BuildConfig.VERSION_NAME)
60-
}
59+
val scrollState = rememberScrollState()
60+
61+
ColumnScrollbar(state = scrollState) {
62+
Column(
63+
modifier = Modifier
64+
.fillMaxWidth()
65+
.padding(horizontal = 20.dp, vertical = 10.dp)
66+
.verticalScroll(scrollState),
67+
verticalArrangement = Arrangement.spacedBy(8.dp)
68+
) {
69+
Column(
70+
modifier = Modifier
71+
.fillMaxWidth()
72+
.wrapContentSize(Alignment.Center),
73+
horizontalAlignment = Alignment.CenterHorizontally
74+
) {
75+
Image(
76+
painter = painterResource(R.drawable.icon),
77+
contentDescription = stringResource(R.string.app_name)
78+
)
79+
Text(
80+
style = MaterialTheme.typography.titleLarge,
81+
text = stringResource(R.string.app_name)
82+
)
83+
Text(text = BuildConfig.VERSION_NAME)
84+
}
6185

62-
Text(text = stringResource(R.string.app_description))
86+
Text(text = stringResource(R.string.app_description))
6387

64-
for (item in ABOUT_ITEMS) {
65-
AboutItem(item)
88+
for (item in ABOUT_ITEMS) {
89+
AboutItem(item)
90+
}
91+
}
6692
}
6793
}
6894

Lines changed: 30 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,197 +1,50 @@
11
package org.schabi.newpipe.ui.components.about
22

3-
import androidx.compose.foundation.clickable
3+
import androidx.compose.foundation.layout.Arrangement
44
import androidx.compose.foundation.layout.Column
55
import androidx.compose.foundation.layout.fillMaxWidth
6-
import androidx.compose.foundation.rememberScrollState
7-
import androidx.compose.foundation.verticalScroll
8-
import androidx.compose.material3.AlertDialog
6+
import androidx.compose.foundation.layout.padding
7+
import androidx.compose.foundation.lazy.rememberLazyListState
98
import androidx.compose.material3.MaterialTheme
109
import androidx.compose.material3.Text
11-
import androidx.compose.material3.TextButton
1210
import androidx.compose.runtime.Composable
13-
import androidx.compose.runtime.LaunchedEffect
1411
import androidx.compose.runtime.NonRestartableComposable
15-
import androidx.compose.runtime.getValue
16-
import androidx.compose.runtime.mutableStateOf
17-
import androidx.compose.runtime.remember
18-
import androidx.compose.runtime.setValue
1912
import androidx.compose.ui.Modifier
20-
import androidx.compose.ui.platform.LocalContext
2113
import androidx.compose.ui.res.stringResource
22-
import androidx.compose.ui.text.AnnotatedString
23-
import androidx.compose.ui.text.SpanStyle
24-
import androidx.compose.ui.text.TextLinkStyles
25-
import androidx.compose.ui.text.fromHtml
26-
import androidx.compose.ui.text.style.TextDecoration
27-
import kotlinx.coroutines.Dispatchers
28-
import kotlinx.coroutines.withContext
14+
import androidx.compose.ui.unit.dp
15+
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
16+
import my.nanihadesuka.compose.LazyColumnScrollbar
2917
import org.schabi.newpipe.R
30-
import org.schabi.newpipe.util.external_communication.ShareUtils
31-
32-
private val SOFTWARE_COMPONENTS = listOf(
33-
SoftwareComponent(
34-
"ACRA", "2013", "Kevin Gaudin",
35-
"https://github.com/ACRA/acra", StandardLicenses.APACHE2
36-
),
37-
SoftwareComponent(
38-
"AndroidX", "2005 - 2011", "The Android Open Source Project",
39-
"https://developer.android.com/jetpack", StandardLicenses.APACHE2
40-
),
41-
SoftwareComponent(
42-
"Coil", "2023", "Coil Contributors",
43-
"https://coil-kt.github.io/coil/", StandardLicenses.APACHE2
44-
),
45-
SoftwareComponent(
46-
"ExoPlayer", "2014 - 2020", "Google, Inc.",
47-
"https://github.com/google/ExoPlayer", StandardLicenses.APACHE2
48-
),
49-
SoftwareComponent(
50-
"GigaGet", "2014 - 2015", "Peter Cai",
51-
"https://github.com/PaperAirplane-Dev-Team/GigaGet", StandardLicenses.GPL3
52-
),
53-
SoftwareComponent(
54-
"Groupie", "2016", "Lisa Wray",
55-
"https://github.com/lisawray/groupie", StandardLicenses.MIT
56-
),
57-
SoftwareComponent(
58-
"Icepick", "2015", "Frankie Sardo",
59-
"https://github.com/frankiesardo/icepick", StandardLicenses.EPL1
60-
),
61-
SoftwareComponent(
62-
"Jsoup", "2009 - 2020", "Jonathan Hedley",
63-
"https://github.com/jhy/jsoup", StandardLicenses.MIT
64-
),
65-
SoftwareComponent(
66-
"LazyColumnScrollbar", "2024", "nani",
67-
"https://github.com/nanihadesuka/LazyColumnScrollbar", StandardLicenses.MIT
68-
),
69-
SoftwareComponent(
70-
"Markwon", "2019", "Dimitry Ivanov",
71-
"https://github.com/noties/Markwon", StandardLicenses.APACHE2
72-
),
73-
SoftwareComponent(
74-
"Material Components for Android", "2016 - 2020", "Google, Inc.",
75-
"https://github.com/material-components/material-components-android",
76-
StandardLicenses.APACHE2
77-
),
78-
SoftwareComponent(
79-
"NewPipe Extractor", "2017 - 2020", "Christian Schabesberger",
80-
"https://github.com/TeamNewPipe/NewPipeExtractor", StandardLicenses.GPL3
81-
),
82-
SoftwareComponent(
83-
"NoNonsense-FilePicker", "2016", "Jonas Kalderstam",
84-
"https://github.com/spacecowboy/NoNonsense-FilePicker", StandardLicenses.MPL2
85-
),
86-
SoftwareComponent(
87-
"OkHttp", "2019", "Square, Inc.",
88-
"https://square.github.io/okhttp/", StandardLicenses.APACHE2
89-
),
90-
SoftwareComponent(
91-
"PrettyTime", "2012 - 2020", "Lincoln Baxter, III",
92-
"https://github.com/ocpsoft/prettytime", StandardLicenses.APACHE2
93-
),
94-
SoftwareComponent(
95-
"ProcessPhoenix", "2015", "Jake Wharton",
96-
"https://github.com/JakeWharton/ProcessPhoenix", StandardLicenses.APACHE2
97-
),
98-
SoftwareComponent(
99-
"RxAndroid", "2015", "The RxAndroid authors",
100-
"https://github.com/ReactiveX/RxAndroid", StandardLicenses.APACHE2
101-
),
102-
SoftwareComponent(
103-
"RxBinding", "2015", "Jake Wharton",
104-
"https://github.com/JakeWharton/RxBinding", StandardLicenses.APACHE2
105-
),
106-
SoftwareComponent(
107-
"RxJava", "2016 - 2020", "RxJava Contributors",
108-
"https://github.com/ReactiveX/RxJava", StandardLicenses.APACHE2
109-
),
110-
SoftwareComponent(
111-
"SearchPreference", "2018", "ByteHamster",
112-
"https://github.com/ByteHamster/SearchPreference", StandardLicenses.MIT
113-
)
114-
)
11518

11619
@Composable
11720
@NonRestartableComposable
11821
fun LicenseTab() {
119-
var selectedLicense by remember { mutableStateOf<SoftwareComponent?>(null) }
120-
val onClick = remember {
121-
{ it: SoftwareComponent -> selectedLicense = it }
122-
}
123-
124-
Text(
125-
text = stringResource(R.string.app_license_title),
126-
style = MaterialTheme.typography.titleLarge
127-
)
128-
Text(
129-
text = stringResource(R.string.app_license),
130-
style = MaterialTheme.typography.bodyMedium
131-
)
132-
133-
Text(
134-
text = stringResource(R.string.title_licenses),
135-
style = MaterialTheme.typography.titleLarge,
136-
)
137-
for (component in SOFTWARE_COMPONENTS) {
138-
LicenseItem(component, onClick)
139-
}
140-
141-
selectedLicense?.let {
142-
var formattedLicense by remember { mutableStateOf("") }
143-
144-
val context = LocalContext.current
145-
LaunchedEffect(key1 = it) {
146-
formattedLicense = withContext(Dispatchers.IO) {
147-
it.license.getFormattedLicense(context)
148-
}
149-
}
150-
151-
AlertDialog(
152-
onDismissRequest = { selectedLicense = null },
153-
confirmButton = {
154-
TextButton(onClick = { ShareUtils.openUrlInApp(context, it.link) }) {
155-
Text(text = stringResource(R.string.open_website_license))
156-
}
157-
},
158-
dismissButton = {
159-
TextButton(onClick = { selectedLicense = null }) {
160-
Text(text = stringResource(R.string.done))
22+
val lazyListState = rememberLazyListState()
23+
24+
LazyColumnScrollbar(state = lazyListState) {
25+
LibrariesContainer(
26+
modifier = Modifier
27+
.fillMaxWidth()
28+
.padding(horizontal = 20.dp, vertical = 10.dp),
29+
lazyListState = lazyListState,
30+
header = {
31+
item {
32+
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
33+
Text(
34+
text = stringResource(R.string.app_license_title),
35+
style = MaterialTheme.typography.titleLarge
36+
)
37+
Text(
38+
text = stringResource(R.string.app_license),
39+
style = MaterialTheme.typography.bodyMedium
40+
)
41+
Text(
42+
text = stringResource(R.string.title_licenses),
43+
style = MaterialTheme.typography.titleLarge,
44+
)
45+
}
16146
}
162-
},
163-
title = {
164-
Text(text = it.name, color = MaterialTheme.colorScheme.onBackground)
165-
},
166-
text = {
167-
val styles = TextLinkStyles(SpanStyle(textDecoration = TextDecoration.Underline))
168-
Text(
169-
modifier = Modifier.verticalScroll(rememberScrollState()),
170-
text = AnnotatedString.fromHtml(formattedLicense, styles)
171-
)
17247
}
17348
)
17449
}
17550
}
176-
177-
@Composable
178-
@NonRestartableComposable
179-
private fun LicenseItem(
180-
softwareComponent: SoftwareComponent,
181-
onClick: (SoftwareComponent) -> Unit
182-
) {
183-
Column(
184-
modifier = Modifier
185-
.fillMaxWidth()
186-
.clickable { onClick(softwareComponent) }
187-
) {
188-
Text(text = softwareComponent.name)
189-
Text(
190-
style = MaterialTheme.typography.bodyMedium,
191-
text = stringResource(
192-
R.string.copyright, softwareComponent.years,
193-
softwareComponent.copyrightOwner, softwareComponent.license.abbreviation
194-
)
195-
)
196-
}
197-
}

0 commit comments

Comments
 (0)