Skip to content

Commit ff78dd1

Browse files
committed
[DO NOT MERGE] Import about screen implementation from refactor
Resolve deprecation errors and adjust code to make testing easier Signed-off-by: Aayush Gupta <[email protected]>
1 parent b01ce34 commit ff78dd1

File tree

8 files changed

+183
-3
lines changed

8 files changed

+183
-3
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ plugins {
1414
alias(libs.plugins.jetbrains.compose.hotreload) apply false
1515
alias(libs.plugins.google.ksp) apply false
1616
alias(libs.plugins.jetbrains.kotlin.parcelize) apply false
17+
alias(libs.plugins.jetbrains.kotlin.serialization) apply false
1718
alias(libs.plugins.sonarqube) apply false
1819
}

composeApp/build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ plugins {
1212
alias(libs.plugins.jetbrains.compose.multiplatform)
1313
alias(libs.plugins.jetbrains.compose.hotreload)
1414
alias(libs.plugins.google.ksp)
15-
alias(libs.plugins.jetbrains.kotlin.parcelize)
15+
alias(libs.plugins.jetbrains.kotlin.serialization)
1616
}
1717

1818
kotlin {
@@ -56,6 +56,10 @@ kotlin {
5656

5757
// Settings
5858
implementation(libs.russhwolf.settings)
59+
60+
// Navigation
61+
implementation(libs.jetbrains.navigation3.ui)
62+
implementation(libs.jetbrains.serialization.json)
5963
}
6064
commonTest.dependencies {
6165
implementation(libs.kotlin.test)
@@ -68,7 +72,7 @@ kotlin {
6872
}
6973
jvmMain.dependencies {
7074
implementation(compose.desktop.currentOs)
71-
implementation(libs.jetbrains.kotlinx.coroutinesSwing)
75+
implementation(libs.jetbrains.coroutines.swing)
7276
}
7377
}
7478

composeApp/src/commonMain/composeResources/values/strings.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@
55
-->
66
<resources>
77
<string name="app_name">NewPipe</string>
8+
9+
<!-- AboutScreen -->
10+
<string name="tab_about">About \u0026 FAQ</string>
11+
<string name="tab_licenses">Licenses</string>
812
</resources>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
package net.newpipe.app.navigation
7+
8+
import androidx.compose.runtime.Composable
9+
import androidx.navigation3.runtime.NavKey
10+
import androidx.navigation3.runtime.entryProvider
11+
import androidx.navigation3.runtime.rememberNavBackStack
12+
import androidx.navigation3.ui.NavDisplay
13+
14+
/**
15+
* Navigation display for compose screens
16+
* @param startDestination Starting destination for the activity/app
17+
*/
18+
@Composable
19+
fun MainNavDisplay(startDestination: NavKey) {
20+
val backstack = rememberNavBackStack(Screen.config, startDestination)
21+
22+
NavDisplay(
23+
backStack = backstack,
24+
entryProvider = entryProvider {
25+
26+
}
27+
)
28+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
package net.newpipe.app.navigation
7+
8+
import androidx.navigation3.runtime.NavKey
9+
import androidx.savedstate.serialization.SavedStateConfiguration
10+
import kotlinx.serialization.Serializable
11+
import kotlinx.serialization.modules.SerializersModule
12+
import kotlinx.serialization.modules.polymorphic
13+
14+
/**
15+
* Destinations for navigation in compose
16+
*/
17+
@Serializable
18+
sealed class Screen : NavKey {
19+
20+
@Serializable
21+
data object About: Screen()
22+
23+
companion object {
24+
val config = SavedStateConfiguration {
25+
serializersModule = SerializersModule {
26+
polymorphic(NavKey::class) {
27+
// TODO: Add all subclasses using a for-each loop
28+
subclass(About::class, About.serializer())
29+
}
30+
}
31+
}
32+
}
33+
}
34+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
3+
* SPDX-License-Identifier: GPL-3.0-or-later
4+
*/
5+
6+
package net.newpipe.app.preview
7+
8+
import androidx.compose.runtime.Composable
9+
import net.newpipe.app.theme.AppTheme
10+
11+
/**
12+
* Template for previewing composable with defaults
13+
*/
14+
@Composable
15+
fun PreviewTemplate(content: @Composable () -> Unit) {
16+
AppTheme(content = content)
17+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 NewPipe contributors <https://newpipe.net>
3+
* SPDX-FileCopyrightText: 2026 NewPipe e.V. <https://newpipe-ev.de>
4+
* SPDX-License-Identifier: GPL-3.0-or-later
5+
*/
6+
7+
package net.newpipe.app.screens
8+
9+
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.fillMaxWidth
12+
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.pager.HorizontalPager
14+
import androidx.compose.foundation.pager.rememberPagerState
15+
import androidx.compose.material3.Scaffold
16+
import androidx.compose.material3.SecondaryTabRow
17+
import androidx.compose.material3.Tab
18+
import androidx.compose.material3.Text
19+
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.rememberCoroutineScope
21+
import androidx.compose.ui.Modifier
22+
import androidx.compose.ui.util.fastForEachIndexed
23+
import kotlinx.coroutines.launch
24+
import net.newpipe.app.preview.PreviewTemplate
25+
import newpipe.composeapp.generated.resources.Res
26+
import newpipe.composeapp.generated.resources.tab_about
27+
import newpipe.composeapp.generated.resources.tab_licenses
28+
import org.jetbrains.compose.resources.stringResource
29+
import org.jetbrains.compose.ui.tooling.preview.Preview
30+
31+
@Composable
32+
fun AboutScreen() {
33+
ScreenContent()
34+
}
35+
36+
@Composable
37+
private fun ScreenContent(onNavigateUp: () -> Unit = {}) {
38+
Scaffold { paddingValues ->
39+
Column(
40+
modifier = Modifier
41+
.fillMaxSize()
42+
.padding(paddingValues)
43+
) {
44+
val pages = listOf(Res.string.tab_about, Res.string.tab_licenses)
45+
val pagerState = rememberPagerState { pages.size }
46+
val coroutineScope = rememberCoroutineScope()
47+
48+
SecondaryTabRow(
49+
modifier = Modifier.fillMaxWidth(),
50+
selectedTabIndex = pagerState.currentPage
51+
) {
52+
pages.fastForEachIndexed { index, pageId ->
53+
Tab(
54+
selected = pagerState.currentPage == index,
55+
text = {
56+
Text(text = stringResource(pageId))
57+
},
58+
onClick = {
59+
coroutineScope.launch {
60+
pagerState.animateScrollToPage(index)
61+
}
62+
}
63+
)
64+
}
65+
}
66+
67+
HorizontalPager(
68+
state = pagerState,
69+
modifier = Modifier.fillMaxSize()
70+
) { page ->
71+
if (page == 0) {
72+
AboutTab()
73+
} else {
74+
LicenseTab()
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
@Preview
82+
@Composable
83+
private fun AboutScreenPreview() {
84+
PreviewTemplate {
85+
ScreenContent()
86+
}
87+
}

gradle/libs.versions.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ material = "1.11.0" # TODO: update to newer version after bug is fixed. See http
4040
media = "1.7.1"
4141
mockitoCore = "5.21.0"
4242
multiplatform = "1.9.3"
43+
navigation3 = "1.0.0-alpha06"
4344
okhttp = "5.3.2"
4445
phoenix = "3.0.0"
4546
#noinspection NewerVersionAvailable,GradleDependency --> 2.8 is the last version, not 2.71828!
@@ -52,6 +53,7 @@ runner = "1.7.0"
5253
rxandroid = "3.0.2"
5354
rxbinding = "4.0.0"
5455
rxjava = "3.1.12"
56+
serialization = "1.9.0"
5557
settings = "1.3.0"
5658
sonarqube = "7.2.1.6560"
5759
statesaver = "1.4.1" # TODO: Drop because it is deprecated and incompatible with KSP2
@@ -116,8 +118,10 @@ google-exoplayer-smoothstreaming = { module = "com.google.android.exoplayer:exop
116118
google-exoplayer-ui = { module = "com.google.android.exoplayer:exoplayer-ui", version.ref = "exoplayer" }
117119
jakewharton-phoenix = { module = "com.jakewharton:process-phoenix", version.ref = "phoenix" }
118120
jakewharton-rxbinding = { module = "com.jakewharton.rxbinding4:rxbinding", version.ref = "rxbinding" }
119-
jetbrains-kotlinx-coroutinesSwing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }
121+
jetbrains-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" }
120122
jetbrains-lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle-jetbrains" }
123+
jetbrains-navigation3-ui = { module = "org.jetbrains.androidx.navigation3:navigation3-ui", version.ref = "navigation3" }
124+
jetbrains-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
121125
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
122126
junit = { module = "junit:junit", version.ref = "junit" }
123127
koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koin-annotations" }
@@ -160,4 +164,5 @@ jetbrains-kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version
160164
jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" } # Needed for statesaver
161165
jetbrains-kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
162166
jetbrains-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
167+
jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
163168
sonarqube = { id = "org.sonarqube", version.ref = "sonarqube" }

0 commit comments

Comments
 (0)