update
This commit is contained in:
@@ -3,7 +3,11 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
|
||||
<application
|
||||
android:banner="@drawable/tv_banner"
|
||||
android:allowBackup="true"
|
||||
android:label="YouTube App"
|
||||
android:usesCleartextTraffic="true"
|
||||
@@ -15,6 +19,7 @@
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.youtubeapp.ui.components
|
||||
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@@ -8,7 +10,13 @@ import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
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.Modifier
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -17,9 +25,18 @@ import com.youtubeapp.data.Video
|
||||
|
||||
@Composable
|
||||
fun VideoCard(video: Video, onClick: () -> Unit) {
|
||||
var isFocused by remember { mutableStateOf(false) }
|
||||
|
||||
Card(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.onFocusChanged { isFocused = it.isFocused }
|
||||
.then(
|
||||
if (isFocused) Modifier.border(3.dp, Color.White, MaterialTheme.shapes.medium)
|
||||
else Modifier
|
||||
)
|
||||
.focusable()
|
||||
) {
|
||||
Column {
|
||||
AsyncImage(
|
||||
|
||||
@@ -47,7 +47,7 @@ fun AllVideosScreen(viewModel: VideoViewModel, onVideoClick: (Int) -> Unit) {
|
||||
}
|
||||
else -> {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(2),
|
||||
columns = GridCells.Adaptive(minSize = 250.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
|
||||
@@ -52,7 +52,7 @@ fun DownloadedScreen(viewModel: VideoViewModel, onVideoClick: (Int) -> Unit) {
|
||||
}
|
||||
else -> {
|
||||
LazyVerticalGrid(
|
||||
columns = GridCells.Fixed(2),
|
||||
columns = GridCells.Adaptive(minSize = 250.dp),
|
||||
contentPadding = PaddingValues(8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.youtubeapp.ui.screens
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
@@ -73,19 +74,38 @@ fun VideoDetailScreen(
|
||||
if (video == null) {
|
||||
Text("Video nicht gefunden", modifier = Modifier.padding(innerPadding).padding(16.dp))
|
||||
} else {
|
||||
Column(
|
||||
BoxWithConstraints(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(innerPadding)
|
||||
) {
|
||||
val isWide = maxWidth > 600.dp
|
||||
|
||||
Column(modifier = Modifier.fillMaxSize()) {
|
||||
AsyncImage(
|
||||
model = video.thumbnail_url,
|
||||
contentDescription = video.title,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.fillMaxWidth(if (isWide) 0.5f else 1f)
|
||||
.aspectRatio(16f / 9f)
|
||||
)
|
||||
VideoInfo(video, isLocal, state.isDownloading, viewModel, videoId, onPlayClick)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun VideoInfo(
|
||||
video: com.youtubeapp.data.Video,
|
||||
isLocal: Boolean,
|
||||
isDownloading: Boolean,
|
||||
viewModel: VideoViewModel,
|
||||
videoId: Int,
|
||||
onPlayClick: () -> Unit
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Text(
|
||||
text = video.title,
|
||||
@@ -119,7 +139,7 @@ fun VideoDetailScreen(
|
||||
Icon(Icons.Default.PlayArrow, contentDescription = null)
|
||||
Text(" Abspielen")
|
||||
}
|
||||
if (state.isDownloading) {
|
||||
if (isDownloading) {
|
||||
OutlinedButton(
|
||||
onClick = {},
|
||||
enabled = false,
|
||||
@@ -151,6 +171,3 @@ fun VideoDetailScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.youtubeapp.ui.screens
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.LayoutInflater
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
@@ -14,6 +15,7 @@ import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.exoplayer.ExoPlayer
|
||||
import androidx.media3.ui.PlayerView
|
||||
import com.youtubeapp.R
|
||||
import com.youtubeapp.ui.viewmodel.VideoViewModel
|
||||
|
||||
@Composable
|
||||
@@ -49,10 +51,12 @@ fun VideoPlayerScreen(videoId: Int, viewModel: VideoViewModel) {
|
||||
|
||||
AndroidView(
|
||||
factory = { ctx ->
|
||||
PlayerView(ctx).apply {
|
||||
player = exoPlayer
|
||||
useController = true
|
||||
}
|
||||
val view = LayoutInflater.from(ctx).inflate(R.layout.player_view, null) as PlayerView
|
||||
view.player = exoPlayer
|
||||
view
|
||||
},
|
||||
update = { view ->
|
||||
view.player = exoPlayer
|
||||
},
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
|
||||
BIN
app/frontend/src/main/res/drawable/tv_banner.png
Normal file
BIN
app/frontend/src/main/res/drawable/tv_banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 942 B |
10
app/frontend/src/main/res/layout/player_view.xml
Normal file
10
app/frontend/src/main/res/layout/player_view.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.media3.ui.PlayerView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/player_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:surface_type="texture_view"
|
||||
app:show_buffering="when_playing"
|
||||
app:use_controller="true" />
|
||||
Reference in New Issue
Block a user