add exoplayer
This commit is contained in:
parent
46134589ae
commit
1c01609af9
|
@ -82,6 +82,7 @@ dependencies {
|
||||||
implementation(libs.androidx.media3.ui)
|
implementation(libs.androidx.media3.ui)
|
||||||
implementation(libs.hilt.android)
|
implementation(libs.hilt.android)
|
||||||
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
implementation(libs.androidx.lifecycle.viewmodel.compose)
|
||||||
|
implementation(libs.androidx.foundation)
|
||||||
ksp(libs.hilt.android.compiler)
|
ksp(libs.hilt.android.compiler)
|
||||||
ksp(libs.androidx.hilt.compiler)
|
ksp(libs.androidx.hilt.compiler)
|
||||||
implementation(libs.androidx.hilt.navigation.compose)
|
implementation(libs.androidx.hilt.navigation.compose)
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<application
|
<application
|
||||||
android:name=".NewPlayerApp"
|
android:name=".NewPlayerApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|
|
@ -1,22 +1,40 @@
|
||||||
package net.newpipe.newplayer.model
|
package net.newpipe.newplayer.model
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import androidx.lifecycle.AndroidViewModel
|
||||||
import androidx.lifecycle.SavedStateHandle
|
import androidx.lifecycle.SavedStateHandle
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import net.newpipe.newplayer.R
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
|
interface VideoPlayerViewModel {
|
||||||
|
val player: Player?
|
||||||
|
}
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class VideoPlayerViewModel @Inject constructor(
|
class VideoPlayerViewModelImpl @Inject constructor(
|
||||||
private val savedStateHandle: SavedStateHandle,
|
private val savedStateHandle: SavedStateHandle,
|
||||||
val player: Player
|
override val player: Player,
|
||||||
): ViewModel() {
|
application: Application
|
||||||
|
) : AndroidViewModel(application), VideoPlayerViewModel {
|
||||||
|
|
||||||
|
val app = getApplication<Application>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
player.prepare()
|
player.prepare()
|
||||||
|
player.setMediaItem(MediaItem.fromUri(app.getString(R.string.ccc_6502_video)))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
player.release()
|
player.release()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val dummy = object : VideoPlayerViewModel {
|
||||||
|
override val player = null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -80,11 +80,9 @@ import net.newpipe.newplayer.ui.theme.video_player_onSurface
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoPlayerControllerUI() {
|
fun VideoPlayerControllerUI() {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier
|
modifier = Modifier.fillMaxSize(), color = Color.Transparent
|
||||||
.fillMaxSize()
|
|
||||||
.background(Color.White)
|
|
||||||
) {
|
) {
|
||||||
Box() {
|
Box(modifier = Modifier.background(Color.Transparent)) {
|
||||||
TopUI(
|
TopUI(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
|
@ -127,23 +125,18 @@ private fun TopUI(modifier: Modifier) {
|
||||||
onClick = { /*TODO*/ },
|
onClick = { /*TODO*/ },
|
||||||
contentPadding = PaddingValues(0.dp),
|
contentPadding = PaddingValues(0.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent, contentColor = video_player_onSurface
|
||||||
contentColor = video_player_onSurface
|
|
||||||
),
|
),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
"1080p",
|
"1080p", fontWeight = FontWeight.Bold, modifier = Modifier.padding(0.dp)
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
modifier = Modifier.padding(0.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
onClick = { /*TODO*/ },
|
onClick = { /*TODO*/ },
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
"1x",
|
"1x", fontWeight = FontWeight.Bold, modifier = Modifier.padding(0.dp)
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
modifier = Modifier.padding(0.dp)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -177,8 +170,7 @@ private fun MainMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Box {
|
Box {
|
||||||
IconButton(onClick = { showMainMenu = true },
|
IconButton(onClick = { showMainMenu = true }, modifier = Modifier.onPlaced {
|
||||||
modifier = Modifier.onPlaced {
|
|
||||||
offsetY = with(pixel_density) {
|
offsetY = with(pixel_density) {
|
||||||
it.size.height.toDp()
|
it.size.height.toDp()
|
||||||
}
|
}
|
||||||
|
@ -189,13 +181,11 @@ private fun MainMenu() {
|
||||||
contentDescription = stringResource(R.string.menu_item_more_settings)
|
contentDescription = stringResource(R.string.menu_item_more_settings)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
DropdownMenu(
|
DropdownMenu(modifier = Modifier.align(Alignment.TopStart),
|
||||||
modifier = Modifier.align(Alignment.TopStart),
|
|
||||||
offset = DpOffset(x = 0.dp, y = -offsetY),
|
offset = DpOffset(x = 0.dp, y = -offsetY),
|
||||||
expanded = showMainMenu,
|
expanded = showMainMenu,
|
||||||
onDismissRequest = { showMainMenu = false }) {
|
onDismissRequest = { showMainMenu = false }) {
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(text = { Text(stringResource(R.string.menu_item_open_in_browser)) },
|
||||||
text = { Text(stringResource(R.string.menu_item_open_in_browser)) },
|
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Language,
|
imageVector = Icons.Filled.Language,
|
||||||
|
@ -203,8 +193,7 @@ private fun MainMenu() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = { /*TODO*/ showMainMenu = false })
|
onClick = { /*TODO*/ showMainMenu = false })
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(text = { Text(stringResource(R.string.menu_item_share_timestamp)) },
|
||||||
text = { Text(stringResource(R.string.menu_item_share_timestamp)) },
|
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Share,
|
imageVector = Icons.Filled.Share,
|
||||||
|
@ -212,17 +201,13 @@ private fun MainMenu() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = { /*TODO*/ showMainMenu = false })
|
onClick = { /*TODO*/ showMainMenu = false })
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(text = { Text(stringResource(R.string.mute)) }, leadingIcon = {
|
||||||
text = { Text(stringResource(R.string.mute)) },
|
|
||||||
leadingIcon = {
|
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.AutoMirrored.Filled.VolumeUp,
|
imageVector = Icons.AutoMirrored.Filled.VolumeUp,
|
||||||
contentDescription = stringResource(R.string.mute)
|
contentDescription = stringResource(R.string.mute)
|
||||||
)
|
)
|
||||||
},
|
}, onClick = { /*TODO*/ showMainMenu = false })
|
||||||
onClick = { /*TODO*/ showMainMenu = false })
|
DropdownMenuItem(text = { Text(stringResource(R.string.menu_item_fit_screen)) },
|
||||||
DropdownMenuItem(
|
|
||||||
text = { Text(stringResource(R.string.menu_item_fit_screen)) },
|
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.FitScreen,
|
imageVector = Icons.Filled.FitScreen,
|
||||||
|
@ -230,8 +215,7 @@ private fun MainMenu() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = { /*TODO*/ showMainMenu = false })
|
onClick = { /*TODO*/ showMainMenu = false })
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(text = { Text(stringResource(R.string.menu_item_sub_titles)) },
|
||||||
text = { Text(stringResource(R.string.menu_item_sub_titles)) },
|
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Subtitles,
|
imageVector = Icons.Filled.Subtitles,
|
||||||
|
@ -239,8 +223,7 @@ private fun MainMenu() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = { /*TODO*/ showMainMenu = false })
|
onClick = { /*TODO*/ showMainMenu = false })
|
||||||
DropdownMenuItem(
|
DropdownMenuItem(text = { Text(stringResource(R.string.menu_item_language)) },
|
||||||
text = { Text(stringResource(R.string.menu_item_language)) },
|
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.Translate,
|
imageVector = Icons.Filled.Translate,
|
||||||
|
@ -264,28 +247,22 @@ private fun CenterUI(modifier: Modifier) {
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
) {
|
) {
|
||||||
CenterControllButton(
|
CenterControllButton(buttonModifier = Modifier.size(80.dp),
|
||||||
buttonModifier = Modifier.size(80.dp),
|
|
||||||
iconModifier = Modifier.size(40.dp),
|
iconModifier = Modifier.size(40.dp),
|
||||||
icon = Icons.Filled.SkipPrevious,
|
icon = Icons.Filled.SkipPrevious,
|
||||||
contentDescriptoion = stringResource(R.string.widget_description_previous_stream),
|
contentDescriptoion = stringResource(R.string.widget_description_previous_stream),
|
||||||
onClick = {}
|
onClick = {})
|
||||||
)
|
|
||||||
|
|
||||||
CenterControllButton(
|
CenterControllButton(buttonModifier = Modifier.size(80.dp),
|
||||||
buttonModifier = Modifier.size(80.dp),
|
|
||||||
iconModifier = Modifier.size(60.dp),
|
iconModifier = Modifier.size(60.dp),
|
||||||
icon = Icons.Filled.PlayArrow,
|
icon = Icons.Filled.PlayArrow,
|
||||||
contentDescriptoion = stringResource(R.string.widget_description_play),
|
contentDescriptoion = stringResource(R.string.widget_description_play),
|
||||||
onClick = {}
|
onClick = {})
|
||||||
)
|
CenterControllButton(buttonModifier = Modifier.size(80.dp),
|
||||||
CenterControllButton(
|
|
||||||
buttonModifier = Modifier.size(80.dp),
|
|
||||||
iconModifier = Modifier.size(40.dp),
|
iconModifier = Modifier.size(40.dp),
|
||||||
icon = Icons.Filled.SkipNext,
|
icon = Icons.Filled.SkipNext,
|
||||||
contentDescriptoion = stringResource(R.string.widget_description_next_stream),
|
contentDescriptoion = stringResource(R.string.widget_description_next_stream),
|
||||||
onClick = {}
|
onClick = {})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,15 +278,12 @@ private fun CenterControllButton(
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
contentPadding = PaddingValues(0.dp),
|
contentPadding = PaddingValues(0.dp),
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent, contentColor = video_player_onSurface
|
||||||
contentColor = video_player_onSurface
|
|
||||||
),
|
),
|
||||||
modifier = buttonModifier
|
modifier = buttonModifier
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = icon,
|
imageVector = icon, modifier = iconModifier, contentDescription = contentDescriptoion
|
||||||
modifier = iconModifier,
|
|
||||||
contentDescription = contentDescriptoion
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,26 +326,43 @@ private fun ViewInFullScreen() {
|
||||||
LockScreenOrientation(orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
|
LockScreenOrientation(orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PreviewBackgroundSurface(
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.fillMaxSize(), color = Color.Black
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview(device = "spec:width=1080px,height=700px,dpi=440,orientation=landscape")
|
@Preview(device = "spec:width=1080px,height=700px,dpi=440,orientation=landscape")
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayerUIPreviewEmbeded() {
|
fun VideoPlayerControllerUIPreviewEmbeded() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI()
|
VideoPlayerControllerUI()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=landscape")
|
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=landscape")
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayerUIPreviewLandscape() {
|
fun VideoPlayerControllerUIPreviewLandscape() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI()
|
VideoPlayerControllerUI()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=portrait")
|
@Preview(device = "spec:width=2340px,height=1080px,dpi=440,orientation=portrait")
|
||||||
@Composable
|
@Composable
|
||||||
fun PlayerUIPreviewPortrait() {
|
fun VideoPlayerControllerUIPreviewPortrait() {
|
||||||
VideoPlayerTheme {
|
VideoPlayerTheme {
|
||||||
|
PreviewBackgroundSurface {
|
||||||
VideoPlayerControllerUI()
|
VideoPlayerControllerUI()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -20,12 +20,85 @@
|
||||||
|
|
||||||
package net.newpipe.newplayer.ui
|
package net.newpipe.newplayer.ui
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
|
import androidx.media3.ui.PlayerView
|
||||||
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
import net.newpipe.newplayer.model.VideoPlayerViewModel
|
||||||
|
import net.newpipe.newplayer.model.VideoPlayerViewModelImpl
|
||||||
|
import net.newpipe.newplayer.ui.theme.VideoPlayerTheme
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoPlayerUI() {
|
fun VideoPlayerUI(
|
||||||
val videoPlayerViewModel: VideoPlayerViewModel = hiltViewModel()
|
viewModel: VideoPlayerViewModel = hiltViewModel<VideoPlayerViewModelImpl>()
|
||||||
|
) {
|
||||||
|
|
||||||
|
var lifecycle by remember {
|
||||||
|
mutableStateOf(Lifecycle.Event.ON_CREATE)
|
||||||
|
}
|
||||||
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
|
DisposableEffect(lifecycleOwner) {
|
||||||
|
val observer = LifecycleEventObserver { _, event ->
|
||||||
|
lifecycle = event
|
||||||
|
}
|
||||||
|
lifecycleOwner.lifecycle.addObserver(observer)
|
||||||
|
|
||||||
|
onDispose {
|
||||||
|
lifecycleOwner.lifecycle.removeObserver(observer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
color = Color.Black
|
||||||
|
) {
|
||||||
|
AndroidView(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
factory = { context ->
|
||||||
|
PlayerView(context).also {
|
||||||
|
it.player = viewModel.player
|
||||||
|
it.useController = false
|
||||||
|
}
|
||||||
|
}, update = {
|
||||||
|
when (lifecycle) {
|
||||||
|
Lifecycle.Event.ON_PAUSE -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Lifecycle.Event.ON_RESUME -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Lifecycle.Event.ON_START -> {
|
||||||
|
it.player?.play()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
VideoPlayerControllerUI()
|
VideoPlayerControllerUI()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(device = "spec:width=1080px,height=700px,dpi=440,orientation=landscape")
|
||||||
|
@Composable
|
||||||
|
fun PlayerUIPreviewEmbeded() {
|
||||||
|
VideoPlayerTheme {
|
||||||
|
VideoPlayerUI(viewModel = VideoPlayerViewModelImpl.dummy)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="ccc_6502_video">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/mp4-h264-HQ/27c3-4159-en-reverse_engineering_mos_6502.mp4</string>
|
||||||
|
<string name="ccc_6502_audio">https://ftp.fau.de/cdn.media.ccc.de/congress/2010/ogg-audio-only/27c3-4159-en-reverse_engineering_mos_6502.ogg</string>
|
||||||
|
</resources>
|
|
@ -26,7 +26,7 @@ junitVersion = "1.2.1"
|
||||||
espressoCore = "3.6.1"
|
espressoCore = "3.6.1"
|
||||||
appcompat = "1.7.0"
|
appcompat = "1.7.0"
|
||||||
material = "1.12.0"
|
material = "1.12.0"
|
||||||
activity = "1.9.0"
|
androidx = "1.9.0"
|
||||||
constraintlayout = "2.1.4"
|
constraintlayout = "2.1.4"
|
||||||
material3 = "1.2.1"
|
material3 = "1.2.1"
|
||||||
uiTooling = "1.6.8"
|
uiTooling = "1.6.8"
|
||||||
|
@ -36,7 +36,7 @@ hiltAndroid = "2.51.1"
|
||||||
hiltCompiler = "1.2.0"
|
hiltCompiler = "1.2.0"
|
||||||
hiltNavigationCompose = "1.2.0"
|
hiltNavigationCompose = "1.2.0"
|
||||||
lifecycleViewmodelCompose = "2.8.3"
|
lifecycleViewmodelCompose = "2.8.3"
|
||||||
kspVersion = "1.9.10-1.0.13"
|
kspVersion = "1.9.0-1.0.13"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
@ -45,9 +45,9 @@ androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "j
|
||||||
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||||
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||||
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "androidx" }
|
||||||
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity" }
|
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidx" }
|
||||||
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
androidx-material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "material3" }
|
||||||
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiTooling" }
|
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling", version.ref = "uiTooling" }
|
||||||
androidx-material-icons-extended-android = { group = "androidx.compose.material", name = "material-icons-extended-android", version.ref = "materialIconsExtendedAndroid" }
|
androidx-material-icons-extended-android = { group = "androidx.compose.material", name = "material-icons-extended-android", version.ref = "materialIconsExtendedAndroid" }
|
||||||
|
@ -58,6 +58,7 @@ androidx-hilt-compiler = { group = "androidx.hilt", name = "hilt-compiler", vers
|
||||||
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
||||||
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltAndroid" }
|
hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hiltAndroid" }
|
||||||
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleViewmodelCompose" }
|
androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleViewmodelCompose" }
|
||||||
|
androidx-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "uiTooling" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|
Loading…
Reference in New Issue