Porównaj commity

...

3 Commity

Autor SHA1 Wiadomość Data
Siddhesh Naik 5fed65cadb
Merge 8c3ac131bc into 879d7a24f0 2024-04-28 21:22:15 +00:00
Siddhesh Naik 8c3ac131bc Introducing Jetpack Compose in NewPipe
This pull request integrates Jetpack Compose into NewPipe by:
- Adding the necessary dependencies and setup.
- This is part of the NewPipe rewrite and fulfils the requirement for
  the planned settings page redesign.
- Introducing a Toolbar composable with theming that aligns with
  NewPipe's design.

Note:
- Theme colors are generated using the Material Theme builder (https://m3.material.io/styles/color/overview).
2024-04-29 02:51:46 +05:30
Siddhesh Naik 879d7a24f0
Fix github worklow for Android tests (#11014)
- The github workflow fails when running android tests.
- The workflow is trying to launch an x86 emulator on aarch-64 (macos-latest) host.
- The macos-latest system seem to be used originally as it supports
  hardware acceleration.
- This is no longer recomended, and ubuntu-latest host can handle the
  same and be faster than macos-latest.

Doc: https://github.com/marketplace/actions/android-emulator-runner#running-hardware-accelerated-emulators-on-linux-runners
2024-04-29 02:45:18 +05:30
5 zmienionych plików z 300 dodań i 2 usunięć

Wyświetl plik

@ -63,8 +63,7 @@ jobs:
path: app/build/outputs/apk/debug/*.apk
test-android:
# macos has hardware acceleration. See android-emulator-runner action
runs-on: macos-latest
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
@ -82,6 +81,12 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: set up JDK 17
uses: actions/setup-java@v4
with:

Wyświetl plik

@ -92,6 +92,7 @@ android {
buildFeatures {
viewBinding true
compose true
}
packagingOptions {
@ -103,6 +104,10 @@ android {
'META-INF/COPYRIGHT']
}
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.3"
}
}
ext {
@ -284,6 +289,12 @@ dependencies {
// Date and time formatting
implementation "org.ocpsoft.prettytime:prettytime:5.0.7.Final"
// Jetpack Compose
implementation(platform('androidx.compose:compose-bom:2024.02.01'))
implementation 'androidx.compose.material3:material3'
implementation 'androidx.activity:activity-compose'
implementation 'androidx.compose.ui:ui-tooling-preview'
/** Debugging **/
// Memory leak detection
debugImplementation "com.squareup.leakcanary:leakcanary-object-watcher-android:${leakCanaryVersion}"
@ -293,6 +304,9 @@ dependencies {
debugImplementation "com.facebook.stetho:stetho:${stethoVersion}"
debugImplementation "com.facebook.stetho:stetho-okhttp3:${stethoVersion}"
// Jetpack Compose
debugImplementation 'androidx.compose.ui:ui-tooling'
/** Testing **/
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.6.0'

Wyświetl plik

@ -0,0 +1,137 @@
package org.schabi.newpipe.ui
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
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.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import org.schabi.newpipe.R
import org.schabi.newpipe.ui.theme.AppTheme
@Composable
fun TextAction(text: String, modifier: Modifier = Modifier) {
Text(text = text, color = MaterialTheme.colorScheme.onSurface, modifier = modifier)
}
@Composable
fun NavigationIcon() {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back",
modifier = Modifier.padding(horizontal = 4.dp)
)
}
@Composable
fun SearchSuggestionItem(text: String) {
// TODO: Add more components here to display all the required details of a search suggestion item.
Text(text = text)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Toolbar(
title: String,
modifier: Modifier = Modifier,
hasNavigationIcon: Boolean = true,
hasSearch: Boolean = false,
onSearchQueryChange: ((String) -> List<String>)? = null,
actions: @Composable RowScope.() -> Unit = {}
) {
var isSearchActive by remember { mutableStateOf(false) }
var query by remember { mutableStateOf("") }
Column {
TopAppBar(
title = { Text(text = title) },
modifier = modifier,
navigationIcon = { if (hasNavigationIcon) NavigationIcon() },
actions = {
actions()
if (hasSearch) {
IconButton(onClick = { isSearchActive = true }) {
Icon(
painterResource(id = R.drawable.ic_search),
contentDescription = stringResource(id = R.string.search),
tint = MaterialTheme.colorScheme.onSurface
)
}
}
}
)
if (isSearchActive) {
SearchBar(
query = query,
onQueryChange = { query = it },
onSearch = {},
placeholder = {
Text(text = stringResource(id = R.string.search))
},
active = true,
onActiveChange = {
isSearchActive = it
},
colors = SearchBarDefaults.colors(
containerColor = MaterialTheme.colorScheme.background,
inputFieldColors = SearchBarDefaults.inputFieldColors(
focusedTextColor = MaterialTheme.colorScheme.onBackground,
unfocusedTextColor = MaterialTheme.colorScheme.onBackground
)
)
) {
onSearchQueryChange?.invoke(query)?.takeIf { it.isNotEmpty() }
?.map { suggestionText -> SearchSuggestionItem(text = suggestionText) }
?: run {
Box(
modifier = Modifier
.fillMaxHeight()
.fillMaxWidth(),
contentAlignment = Alignment.Center
) {
Column {
Text(text = "╰(°●°╰)")
Text(text = stringResource(id = R.string.search_no_results))
}
}
}
}
}
}
}
@Preview
@Composable
fun ToolbarPreview() {
AppTheme {
Toolbar(
title = "Title",
hasSearch = true,
onSearchQueryChange = { emptyList() },
actions = {
TextAction(text = "Action1")
TextAction(text = "Action2")
}
)
}
}

Wyświetl plik

@ -0,0 +1,63 @@
package org.schabi.newpipe.ui.theme
import androidx.compose.ui.graphics.Color
val md_theme_light_primary = Color(0xFFBB171C)
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
val md_theme_light_primaryContainer = Color(0xFFFFDAD6)
val md_theme_light_onPrimaryContainer = Color(0xFF410002)
val md_theme_light_secondary = Color(0xFF984061)
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
val md_theme_light_secondaryContainer = Color(0xFFFFD9E2)
val md_theme_light_onSecondaryContainer = Color(0xFF3E001D)
val md_theme_light_tertiary = Color(0xFF006874)
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
val md_theme_light_tertiaryContainer = Color(0xFF97F0FF)
val md_theme_light_onTertiaryContainer = Color(0xFF001F24)
val md_theme_light_error = Color(0xFFBA1A1A)
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
val md_theme_light_onError = Color(0xFFFFFFFF)
val md_theme_light_onErrorContainer = Color(0xFF410002)
val md_theme_light_background = Color(0xFFEEEEEE)
val md_theme_light_onBackground = Color(0xFF1B1B1B)
val md_theme_light_surface = Color(0xFFE53835)
val md_theme_light_onSurface = Color(0xFFFFFFFF)
val md_theme_light_surfaceVariant = Color(0xFFF5DDDB)
val md_theme_light_onSurfaceVariant = Color(0xFF534341)
val md_theme_light_outline = Color(0xFF857371)
val md_theme_light_inverseOnSurface = Color(0xFFD6F6FF)
val md_theme_light_inverseSurface = Color(0xFF00363F)
val md_theme_light_inversePrimary = Color(0xFFFFB4AC)
val md_theme_light_surfaceTint = Color(0xFFBB171C)
val md_theme_light_outlineVariant = Color(0xFFD8C2BF)
val md_theme_light_scrim = Color(0xFF000000)
val md_theme_dark_primary = Color(0xFFFFB4AC)
val md_theme_dark_onPrimary = Color(0xFF690006)
val md_theme_dark_primaryContainer = Color(0xFF93000D)
val md_theme_dark_onPrimaryContainer = Color(0xFFFFDAD6)
val md_theme_dark_secondary = Color(0xFFFFB1C8)
val md_theme_dark_onSecondary = Color(0xFF5E1133)
val md_theme_dark_secondaryContainer = Color(0xFF7B2949)
val md_theme_dark_onSecondaryContainer = Color(0xFFFFD9E2)
val md_theme_dark_tertiary = Color(0xFF4FD8EB)
val md_theme_dark_onTertiary = Color(0xFF00363D)
val md_theme_dark_tertiaryContainer = Color(0xFF004F58)
val md_theme_dark_onTertiaryContainer = Color(0xFF97F0FF)
val md_theme_dark_error = Color(0xFFFFB4AB)
val md_theme_dark_errorContainer = Color(0xFF93000A)
val md_theme_dark_onError = Color(0xFF690005)
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
val md_theme_dark_background = Color(0xFF212121)
val md_theme_dark_onBackground = Color(0xFFFFFFFF)
val md_theme_dark_surface = Color(0xFF992521)
val md_theme_dark_onSurface = Color(0xFFFFFFFF)
val md_theme_dark_surfaceVariant = Color(0xFF534341)
val md_theme_dark_onSurfaceVariant = Color(0xFFD8C2BF)
val md_theme_dark_outline = Color(0xFFA08C8A)
val md_theme_dark_inverseOnSurface = Color(0xFF001F25)
val md_theme_dark_inverseSurface = Color(0xFFA6EEFF)
val md_theme_dark_inversePrimary = Color(0xFFBB171C)
val md_theme_dark_surfaceTint = Color(0xFFFFB4AC)
val md_theme_dark_outlineVariant = Color(0xFF534341)
val md_theme_dark_scrim = Color(0xFF000000)

Wyświetl plik

@ -0,0 +1,79 @@
package org.schabi.newpipe.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
private val LightColors = lightColorScheme(
primary = md_theme_light_primary,
onPrimary = md_theme_light_onPrimary,
primaryContainer = md_theme_light_primaryContainer,
onPrimaryContainer = md_theme_light_onPrimaryContainer,
secondary = md_theme_light_secondary,
onSecondary = md_theme_light_onSecondary,
secondaryContainer = md_theme_light_secondaryContainer,
onSecondaryContainer = md_theme_light_onSecondaryContainer,
tertiary = md_theme_light_tertiary,
onTertiary = md_theme_light_onTertiary,
tertiaryContainer = md_theme_light_tertiaryContainer,
onTertiaryContainer = md_theme_light_onTertiaryContainer,
error = md_theme_light_error,
errorContainer = md_theme_light_errorContainer,
onError = md_theme_light_onError,
onErrorContainer = md_theme_light_onErrorContainer,
background = md_theme_light_background,
onBackground = md_theme_light_onBackground,
surface = md_theme_light_surface,
onSurface = md_theme_light_onSurface,
surfaceVariant = md_theme_light_surfaceVariant,
onSurfaceVariant = md_theme_light_onSurfaceVariant,
outline = md_theme_light_outline,
inverseOnSurface = md_theme_light_inverseOnSurface,
inverseSurface = md_theme_light_inverseSurface,
inversePrimary = md_theme_light_inversePrimary,
surfaceTint = md_theme_light_surfaceTint,
outlineVariant = md_theme_light_outlineVariant,
scrim = md_theme_light_scrim,
)
private val DarkColors = darkColorScheme(
primary = md_theme_dark_primary,
onPrimary = md_theme_dark_onPrimary,
primaryContainer = md_theme_dark_primaryContainer,
onPrimaryContainer = md_theme_dark_onPrimaryContainer,
secondary = md_theme_dark_secondary,
onSecondary = md_theme_dark_onSecondary,
secondaryContainer = md_theme_dark_secondaryContainer,
onSecondaryContainer = md_theme_dark_onSecondaryContainer,
tertiary = md_theme_dark_tertiary,
onTertiary = md_theme_dark_onTertiary,
tertiaryContainer = md_theme_dark_tertiaryContainer,
onTertiaryContainer = md_theme_dark_onTertiaryContainer,
error = md_theme_dark_error,
errorContainer = md_theme_dark_errorContainer,
onError = md_theme_dark_onError,
onErrorContainer = md_theme_dark_onErrorContainer,
background = md_theme_dark_background,
onBackground = md_theme_dark_onBackground,
surface = md_theme_dark_surface,
onSurface = md_theme_dark_onSurface,
surfaceVariant = md_theme_dark_surfaceVariant,
onSurfaceVariant = md_theme_dark_onSurfaceVariant,
outline = md_theme_dark_outline,
inverseOnSurface = md_theme_dark_inverseOnSurface,
inverseSurface = md_theme_dark_inverseSurface,
inversePrimary = md_theme_dark_inversePrimary,
surfaceTint = md_theme_dark_surfaceTint,
outlineVariant = md_theme_dark_outlineVariant,
scrim = md_theme_dark_scrim,
)
@Composable
fun AppTheme(useDarkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
MaterialTheme(
colorScheme = if (useDarkTheme) DarkColors else LightColors,
content = content
)
}