mirror of
https://github.com/TeamNewPipe/NewPipe.git
synced 2025-10-03 09:49:21 +02:00
Merge 39a89d425c
into abfde872f1
This commit is contained in:
commit
c19355916c
6 changed files with 143 additions and 68 deletions
|
@ -1,23 +1,31 @@
|
||||||
package org.schabi.newpipe.settings
|
package org.schabi.newpipe.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.unit.dp
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
|
import org.schabi.newpipe.ui.SettingsRoutes
|
||||||
import org.schabi.newpipe.ui.TextPreference
|
import org.schabi.newpipe.ui.TextPreference
|
||||||
|
import org.schabi.newpipe.ui.theme.SizeTokens.SpacingExtraSmall
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsScreen(
|
fun SettingsScreen(
|
||||||
onSelectSettingOption: (SettingsScreenKey) -> Unit,
|
onSelectSettingOption: (settingsRoute: SettingsRoutes) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Column(modifier = modifier) {
|
Column(modifier = modifier) {
|
||||||
TextPreference(
|
TextPreference(
|
||||||
title = R.string.settings_category_debug_title,
|
title = R.string.settings_category_debug_title,
|
||||||
onClick = { onSelectSettingOption(SettingsScreenKey.DEBUG) }
|
onClick = { onSelectSettingOption(SettingsRoutes.SettingsDebugRoute) }
|
||||||
|
)
|
||||||
|
HorizontalDivider(
|
||||||
|
color = MaterialTheme.colorScheme.onBackground,
|
||||||
|
thickness = 0.6.dp,
|
||||||
|
modifier = Modifier.padding(horizontal = SpacingExtraSmall)
|
||||||
)
|
)
|
||||||
HorizontalDivider(color = Color.Black)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,21 +10,19 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import androidx.navigation.navArgument
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
import org.schabi.newpipe.settings.viewmodel.SettingsViewModel
|
import org.schabi.newpipe.settings.viewmodel.SettingsViewModel
|
||||||
|
import org.schabi.newpipe.ui.SettingsRoutes
|
||||||
import org.schabi.newpipe.ui.Toolbar
|
import org.schabi.newpipe.ui.Toolbar
|
||||||
import org.schabi.newpipe.ui.theme.AppTheme
|
import org.schabi.newpipe.ui.theme.AppTheme
|
||||||
|
|
||||||
const val SCREEN_TITLE_KEY = "SCREEN_TITLE_KEY"
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class SettingsV2Activity : ComponentActivity() {
|
class SettingsV2Activity : ComponentActivity() {
|
||||||
|
|
||||||
|
@ -35,37 +33,44 @@ class SettingsV2Activity : ComponentActivity() {
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
var screenTitle by remember { mutableIntStateOf(SettingsScreenKey.ROOT.screenTitle) }
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
navController.addOnDestinationChangedListener { _, _, arguments ->
|
@StringRes val screenTitleRes by remember(navBackStackEntry) {
|
||||||
screenTitle =
|
mutableIntStateOf(
|
||||||
arguments?.getInt(SCREEN_TITLE_KEY) ?: SettingsScreenKey.ROOT.screenTitle
|
when (navBackStackEntry?.destination?.route) {
|
||||||
|
SettingsRoutes.SettingsMainRoute::class.java.canonicalName -> SettingsRoutes.SettingsMainRoute.screenTitleRes
|
||||||
|
SettingsRoutes.SettingsDebugRoute::class.java.canonicalName -> SettingsRoutes.SettingsDebugRoute.screenTitleRes
|
||||||
|
else -> R.string.settings
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
AppTheme {
|
AppTheme {
|
||||||
Scaffold(topBar = {
|
Scaffold(topBar = {
|
||||||
Toolbar(
|
Toolbar(
|
||||||
title = stringResource(id = screenTitle),
|
title = stringResource(screenTitleRes),
|
||||||
|
onNavigateBack = {
|
||||||
|
if (!navController.popBackStack()) {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
},
|
||||||
hasSearch = true,
|
hasSearch = true,
|
||||||
onSearchQueryChange = null // TODO: Add suggestions logic
|
onSearch = {
|
||||||
|
// TODO: Add suggestions logic
|
||||||
|
},
|
||||||
|
searchResults = emptyList()
|
||||||
)
|
)
|
||||||
}) { padding ->
|
}) { padding ->
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = SettingsScreenKey.ROOT.name,
|
startDestination = SettingsRoutes.SettingsMainRoute,
|
||||||
modifier = Modifier.padding(padding)
|
modifier = Modifier.padding(padding)
|
||||||
) {
|
) {
|
||||||
composable(
|
composable<SettingsRoutes.SettingsMainRoute> {
|
||||||
SettingsScreenKey.ROOT.name,
|
SettingsScreen(onSelectSettingOption = { route ->
|
||||||
listOf(createScreenTitleArg(SettingsScreenKey.ROOT.screenTitle))
|
navController.navigate(route)
|
||||||
) {
|
|
||||||
SettingsScreen(onSelectSettingOption = { screen ->
|
|
||||||
navController.navigate(screen.name)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
composable(
|
composable<SettingsRoutes.SettingsDebugRoute> {
|
||||||
SettingsScreenKey.DEBUG.name,
|
|
||||||
listOf(createScreenTitleArg(SettingsScreenKey.DEBUG.screenTitle))
|
|
||||||
) {
|
|
||||||
DebugScreen(settingsViewModel)
|
DebugScreen(settingsViewModel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,12 +79,3 @@ class SettingsV2Activity : ComponentActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createScreenTitleArg(@StringRes screenTitle: Int) = navArgument(SCREEN_TITLE_KEY) {
|
|
||||||
defaultValue = screenTitle
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class SettingsScreenKey(@StringRes val screenTitle: Int) {
|
|
||||||
ROOT(R.string.settings),
|
|
||||||
DEBUG(R.string.settings_category_debug_title)
|
|
||||||
}
|
|
||||||
|
|
17
app/src/main/java/org/schabi/newpipe/ui/SettingsRoutes.kt
Normal file
17
app/src/main/java/org/schabi/newpipe/ui/SettingsRoutes.kt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
package org.schabi.newpipe.ui
|
||||||
|
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.schabi.newpipe.R
|
||||||
|
|
||||||
|
// Settings screens
|
||||||
|
@Serializable
|
||||||
|
sealed class SettingsRoutes(
|
||||||
|
@get:StringRes
|
||||||
|
val screenTitleRes: Int
|
||||||
|
) {
|
||||||
|
@Serializable
|
||||||
|
object SettingsMainRoute : SettingsRoutes(R.string.settings)
|
||||||
|
@Serializable
|
||||||
|
object SettingsDebugRoute : SettingsRoutes(R.string.settings_category_debug_title)
|
||||||
|
}
|
|
@ -1,45 +1,60 @@
|
||||||
package org.schabi.newpipe.ui
|
package org.schabi.newpipe.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.RowScope
|
import androidx.compose.foundation.layout.RowScope
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.SearchBar
|
import androidx.compose.material3.SearchBar
|
||||||
|
import androidx.compose.material3.SearchBarDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.semantics.isTraversalGroup
|
||||||
|
import androidx.compose.ui.semantics.semantics
|
||||||
|
import androidx.compose.ui.semantics.traversalIndex
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import org.schabi.newpipe.R
|
import org.schabi.newpipe.R
|
||||||
import org.schabi.newpipe.ui.theme.AppTheme
|
import org.schabi.newpipe.ui.theme.AppTheme
|
||||||
import org.schabi.newpipe.ui.theme.SizeTokens
|
import org.schabi.newpipe.ui.theme.SizeTokens
|
||||||
|
import org.schabi.newpipe.ui.theme.SizeTokens.SpacingExtraSmall
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TextAction(text: String, modifier: Modifier = Modifier) {
|
fun TextAction(text: String, modifier: Modifier = Modifier) {
|
||||||
Text(text = text, color = MaterialTheme.colorScheme.onSurface, modifier = modifier)
|
Text(text = text, color = MaterialTheme.colorScheme.onPrimary, modifier = modifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun NavigationIcon() {
|
fun NavigationIcon(navigateBack: () -> Unit) {
|
||||||
Icon(
|
IconButton(onClick = navigateBack) {
|
||||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back",
|
Icon(
|
||||||
modifier = Modifier.padding(horizontal = SizeTokens.SpacingExtraSmall)
|
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
)
|
contentDescription = "Back",
|
||||||
|
modifier = Modifier.padding(horizontal = SizeTokens.SpacingExtraSmall)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
@ -53,19 +68,27 @@ fun SearchSuggestionItem(text: String) {
|
||||||
fun Toolbar(
|
fun Toolbar(
|
||||||
title: String,
|
title: String,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
hasNavigationIcon: Boolean = true,
|
onNavigateBack: (() -> Unit)? = null,
|
||||||
hasSearch: Boolean = false,
|
hasSearch: Boolean = false,
|
||||||
onSearchQueryChange: ((String) -> List<String>)? = null,
|
onSearch: (String) -> Unit,
|
||||||
|
searchResults: List<String>,
|
||||||
actions: @Composable RowScope.() -> Unit = {}
|
actions: @Composable RowScope.() -> Unit = {}
|
||||||
) {
|
) {
|
||||||
var isSearchActive by remember { mutableStateOf(false) }
|
var isSearchActive by remember { mutableStateOf(false) }
|
||||||
var query by remember { mutableStateOf("") }
|
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||||
|
val textFieldState = rememberTextFieldState()
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text(text = title) },
|
title = { Text(text = title) },
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
navigationIcon = { if (hasNavigationIcon) NavigationIcon() },
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
titleContentColor = MaterialTheme.colorScheme.onPrimary,
|
||||||
|
),
|
||||||
|
navigationIcon = {
|
||||||
|
onNavigateBack?.let { NavigationIcon(onNavigateBack) }
|
||||||
|
},
|
||||||
actions = {
|
actions = {
|
||||||
actions()
|
actions()
|
||||||
if (hasSearch) {
|
if (hasSearch) {
|
||||||
|
@ -73,40 +96,67 @@ fun Toolbar(
|
||||||
Icon(
|
Icon(
|
||||||
painterResource(id = R.drawable.ic_search),
|
painterResource(id = R.drawable.ic_search),
|
||||||
contentDescription = stringResource(id = R.string.search),
|
contentDescription = stringResource(id = R.string.search),
|
||||||
tint = MaterialTheme.colorScheme.onSurface
|
tint = MaterialTheme.colorScheme.onPrimary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
if (isSearchActive) {
|
if (isSearchActive) {
|
||||||
SearchBar(
|
Box(
|
||||||
query = query,
|
modifier
|
||||||
onQueryChange = { query = it },
|
.fillMaxSize()
|
||||||
onSearch = {},
|
.semantics { isTraversalGroup = true }
|
||||||
placeholder = {
|
|
||||||
Text(text = stringResource(id = R.string.search))
|
|
||||||
},
|
|
||||||
active = true,
|
|
||||||
onActiveChange = {
|
|
||||||
isSearchActive = it
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
onSearchQueryChange?.invoke(query)?.takeIf { it.isNotEmpty() }
|
SearchBar(
|
||||||
?.map { suggestionText -> SearchSuggestionItem(text = suggestionText) }
|
modifier = Modifier
|
||||||
?: run {
|
.align(Alignment.TopCenter)
|
||||||
|
.semantics { traversalIndex = 0f },
|
||||||
|
inputField = {
|
||||||
|
SearchBarDefaults.InputField(
|
||||||
|
query = textFieldState.text.toString(),
|
||||||
|
onQueryChange = { textFieldState.edit { replace(0, length, it) } },
|
||||||
|
onSearch = {
|
||||||
|
onSearch(textFieldState.text.toString())
|
||||||
|
expanded = false
|
||||||
|
},
|
||||||
|
expanded = expanded,
|
||||||
|
onExpandedChange = { expanded = it },
|
||||||
|
placeholder = { Text(text = stringResource(id = R.string.search)) },
|
||||||
|
modifier = Modifier.padding(horizontal = SpacingExtraSmall)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
expanded = expanded,
|
||||||
|
onExpandedChange = { expanded = it },
|
||||||
|
) {
|
||||||
|
if (searchResults.isEmpty()) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxSize()
|
||||||
.fillMaxWidth(),
|
.padding(SpacingExtraSmall),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center,
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
Text(text = "╰(°●°╰)")
|
Text(text = "╰(°●°╰)")
|
||||||
Text(text = stringResource(id = R.string.search_no_results))
|
Text(text = stringResource(id = R.string.search_no_results))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
LazyColumn {
|
||||||
|
items(searchResults) { result ->
|
||||||
|
ListItem(
|
||||||
|
headlineContent = { SearchSuggestionItem(result) },
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable {
|
||||||
|
textFieldState.edit { replace(0, length, result) }
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
.fillMaxWidth()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +169,8 @@ fun ToolbarPreview() {
|
||||||
Toolbar(
|
Toolbar(
|
||||||
title = "Title",
|
title = "Title",
|
||||||
hasSearch = true,
|
hasSearch = true,
|
||||||
onSearchQueryChange = { emptyList() },
|
onSearch = {},
|
||||||
|
searchResults = emptyList(),
|
||||||
actions = {
|
actions = {
|
||||||
TextAction(text = "Action1")
|
TextAction(text = "Action1")
|
||||||
TextAction(text = "Action2")
|
TextAction(text = "Action2")
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package org.schabi.newpipe.ui.theme
|
package org.schabi.newpipe.ui.theme
|
||||||
|
|
||||||
|
// Color.kt is generated using the Material theme builder https://material-foundation.github.io/material-theme-builder/
|
||||||
|
// TODO: Update the colors to properly match the existing color scheme + also add colors schemes for other services
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
val primaryLight = Color(0xFF904A45)
|
val primaryLight = Color(0xFFE53935)
|
||||||
val onPrimaryLight = Color(0xFFFFFFFF)
|
val onPrimaryLight = Color(0xFFFFFFFF)
|
||||||
val primaryContainerLight = Color(0xFFFFDAD6)
|
val primaryContainerLight = Color(0xFFFFDAD6)
|
||||||
val onPrimaryContainerLight = Color(0xFF3B0908)
|
val onPrimaryContainerLight = Color(0xFF3B0908)
|
||||||
|
@ -38,8 +41,8 @@ val surfaceContainerLight = Color(0xFFFCEAE8)
|
||||||
val surfaceContainerHighLight = Color(0xFFF6E4E2)
|
val surfaceContainerHighLight = Color(0xFFF6E4E2)
|
||||||
val surfaceContainerHighestLight = Color(0xFFF1DEDC)
|
val surfaceContainerHighestLight = Color(0xFFF1DEDC)
|
||||||
|
|
||||||
val primaryDark = Color(0xFFFFB3AC)
|
val primaryDark = Color(0xFF992722)
|
||||||
val onPrimaryDark = Color(0xFF571E1B)
|
val onPrimaryDark = Color(0xFFF4D2D2)
|
||||||
val primaryContainerDark = Color(0xFF73332F)
|
val primaryContainerDark = Color(0xFF73332F)
|
||||||
val onPrimaryContainerDark = Color(0xFFFFDAD6)
|
val onPrimaryContainerDark = Color(0xFFFFDAD6)
|
||||||
val secondaryDark = Color(0xFFE7BDB8)
|
val secondaryDark = Color(0xFFE7BDB8)
|
||||||
|
|
|
@ -137,7 +137,7 @@ kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-p
|
||||||
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
|
kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" }
|
||||||
kotlinx-coroutines-rx3 = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-rx3", version.ref = "kotlinxCoroutinesRx3" }
|
kotlinx-coroutines-rx3 = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-rx3", version.ref = "kotlinxCoroutinesRx3" }
|
||||||
kotlinx-serialization = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin" }
|
kotlinx-serialization = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin" }
|
||||||
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
|
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
|
||||||
lazycolumnscrollbar = { group = "com.github.nanihadesuka", name = "LazyColumnScrollbar", version.ref = "lazycolumnscrollbar" }
|
lazycolumnscrollbar = { group = "com.github.nanihadesuka", name = "LazyColumnScrollbar", version.ref = "lazycolumnscrollbar" }
|
||||||
leakcanary-android-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" }
|
leakcanary-android-core = { module = "com.squareup.leakcanary:leakcanary-android-core", version.ref = "leakcanary" }
|
||||||
leakcanary-object-watcher = { group = "com.squareup.leakcanary", name = "leakcanary-object-watcher-android", version.ref = "leakcanary" }
|
leakcanary-object-watcher = { group = "com.squareup.leakcanary", name = "leakcanary-object-watcher-android", version.ref = "leakcanary" }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue