Skip to content

Commit f836862

Browse files
committed
完善播放页
1 parent 0b16bf5 commit f836862

File tree

3 files changed

+225
-21
lines changed

3 files changed

+225
-21
lines changed

app/src/main/kotlin/dev/aaa1115910/bv/mobile/activities/VideoPlayerActivity.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSiz
99
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
1010
import androidx.lifecycle.lifecycleScope
1111
import androidx.media3.exoplayer.ExoPlayer
12-
import dev.aaa1115910.bv.mobile.viewmodel.MobileVideoPlayerViewModel
1312
import dev.aaa1115910.bv.mobile.screen.VideoPlayerScreen
1413
import dev.aaa1115910.bv.mobile.theme.BVMobileTheme
14+
import dev.aaa1115910.bv.mobile.viewmodel.MobileVideoPlayerViewModel
1515
import dev.aaa1115910.bv.util.fInfo
1616
import kotlinx.coroutines.Dispatchers
1717
import kotlinx.coroutines.launch
@@ -67,4 +67,9 @@ class VideoPlayerActivity : ComponentActivity() {
6767
super.onDestroy()
6868
playerViewModel.videoPlayer?.release()
6969
}
70+
71+
override fun onPause() {
72+
super.onPause()
73+
playerViewModel.videoPlayer?.pause()
74+
}
7075
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package dev.aaa1115910.bv.mobile.component.videocard
2+
3+
import androidx.compose.foundation.background
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.aspectRatio
9+
import androidx.compose.foundation.layout.fillMaxHeight
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.height
12+
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.layout.size
14+
import androidx.compose.material3.Icon
15+
import androidx.compose.material3.MaterialTheme
16+
import androidx.compose.material3.Surface
17+
import androidx.compose.material3.Text
18+
import androidx.compose.runtime.Composable
19+
import androidx.compose.ui.Alignment
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.draw.clip
22+
import androidx.compose.ui.graphics.Color
23+
import androidx.compose.ui.layout.ContentScale
24+
import androidx.compose.ui.res.painterResource
25+
import androidx.compose.ui.text.style.TextOverflow
26+
import androidx.compose.ui.tooling.preview.Preview
27+
import androidx.compose.ui.unit.dp
28+
import coil.compose.AsyncImage
29+
import dev.aaa1115910.biliapi.entity.user.Author
30+
import dev.aaa1115910.biliapi.entity.video.RelatedVideo
31+
import dev.aaa1115910.bv.R
32+
import dev.aaa1115910.bv.mobile.theme.BVMobileTheme
33+
import dev.aaa1115910.bv.util.formatMinSec
34+
35+
@Composable
36+
fun RelatedVideoItem(
37+
modifier: Modifier = Modifier,
38+
relatedVideo: RelatedVideo,
39+
onClick: (RelatedVideo) -> Unit = {}
40+
) {
41+
Surface(
42+
modifier = modifier,
43+
onClick = { onClick(relatedVideo) },
44+
) {
45+
Row(
46+
modifier = Modifier
47+
.fillMaxWidth()
48+
.height(97.dp)
49+
.padding(8.dp),
50+
horizontalArrangement = Arrangement.spacedBy(8.dp)
51+
) {
52+
Box {
53+
AsyncImage(
54+
modifier = Modifier
55+
.fillMaxHeight()
56+
.aspectRatio(16 / 9f)
57+
.background(Color.Gray, MaterialTheme.shapes.small)
58+
.clip(MaterialTheme.shapes.small),
59+
model = relatedVideo.cover,
60+
contentDescription = null,
61+
contentScale = ContentScale.FillBounds
62+
)
63+
Surface(
64+
modifier = Modifier
65+
.align(Alignment.BottomEnd)
66+
.padding(4.dp),
67+
color = Color.Black.copy(alpha = 0.3f),
68+
shape = MaterialTheme.shapes.extraSmall
69+
) {
70+
Text(
71+
modifier = Modifier
72+
.padding(horizontal = 4.dp),
73+
text = (relatedVideo.duration * 1000L).formatMinSec(),
74+
style = MaterialTheme.typography.bodySmall,
75+
color = Color.White
76+
)
77+
}
78+
}
79+
80+
Column(
81+
modifier = Modifier.fillMaxHeight(),
82+
verticalArrangement = Arrangement.SpaceBetween
83+
) {
84+
Text(
85+
modifier = Modifier.fillMaxWidth(),
86+
text = relatedVideo.title,
87+
//style = MaterialTheme.typography.titleMedium,
88+
minLines = 2,
89+
maxLines = 2,
90+
overflow = TextOverflow.Ellipsis
91+
)
92+
Row(
93+
verticalAlignment = Alignment.CenterVertically,
94+
horizontalArrangement = Arrangement.spacedBy(2.dp)
95+
) {
96+
Icon(
97+
modifier = Modifier.size(16.dp),
98+
painter = painterResource(id = R.drawable.ic_up),
99+
contentDescription = null,
100+
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
101+
)
102+
Text(
103+
text = "${relatedVideo.author?.name}",
104+
style = MaterialTheme.typography.bodySmall,
105+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
106+
)
107+
}
108+
Row(
109+
horizontalArrangement = Arrangement.spacedBy(8.dp)
110+
) {
111+
Row(
112+
verticalAlignment = Alignment.CenterVertically,
113+
horizontalArrangement = Arrangement.spacedBy(2.dp)
114+
) {
115+
Icon(
116+
painter = painterResource(id = R.drawable.ic_play_count),
117+
contentDescription = null,
118+
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
119+
)
120+
Text(
121+
text = "${relatedVideo.view}",
122+
style = MaterialTheme.typography.bodySmall,
123+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
124+
)
125+
}
126+
Row(
127+
verticalAlignment = Alignment.CenterVertically,
128+
horizontalArrangement = Arrangement.spacedBy(2.dp)
129+
) {
130+
Icon(
131+
painter = painterResource(id = R.drawable.ic_danmaku_count),
132+
contentDescription = null,
133+
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
134+
)
135+
Text(
136+
text = "${relatedVideo.danmaku}",
137+
style = MaterialTheme.typography.bodySmall,
138+
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.8f)
139+
)
140+
}
141+
142+
}
143+
}
144+
}
145+
}
146+
147+
}
148+
149+
@Preview
150+
@Composable
151+
fun RelatedVideoItemPreview() {
152+
BVMobileTheme {
153+
Surface {
154+
RelatedVideoItem(
155+
relatedVideo = RelatedVideo(
156+
aid = 0,
157+
title = "This is a video title! This is a video title! This is a video title! ",
158+
cover = "",
159+
author = Author(
160+
mid = 0,
161+
name = "Up name",
162+
face = "",
163+
),
164+
duration = 5346,
165+
view = 3521,
166+
danmaku = 543,
167+
jumpToSeason = false,
168+
epid = null
169+
)
170+
)
171+
}
172+
}
173+
}

app/src/main/kotlin/dev/aaa1115910/bv/mobile/screen/VideoPlayerScreen.kt

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ import androidx.compose.foundation.layout.Arrangement
1111
import androidx.compose.foundation.layout.Box
1212
import androidx.compose.foundation.layout.Column
1313
import androidx.compose.foundation.layout.Row
14+
import androidx.compose.foundation.layout.Spacer
1415
import androidx.compose.foundation.layout.aspectRatio
1516
import androidx.compose.foundation.layout.fillMaxHeight
1617
import androidx.compose.foundation.layout.fillMaxSize
1718
import androidx.compose.foundation.layout.fillMaxWidth
1819
import androidx.compose.foundation.layout.height
20+
import androidx.compose.foundation.layout.navigationBarsPadding
1921
import androidx.compose.foundation.layout.padding
2022
import androidx.compose.foundation.layout.size
2123
import androidx.compose.foundation.lazy.LazyColumn
22-
import androidx.compose.foundation.lazy.LazyListScope
24+
import androidx.compose.foundation.lazy.items
2325
import androidx.compose.foundation.pager.HorizontalPager
2426
import androidx.compose.foundation.pager.rememberPagerState
2527
import androidx.compose.foundation.shape.CircleShape
@@ -60,9 +62,12 @@ import androidx.compose.ui.zIndex
6062
import coil.compose.AsyncImage
6163
import com.google.accompanist.systemuicontroller.rememberSystemUiController
6264
import dev.aaa1115910.bv.R
65+
import dev.aaa1115910.bv.mobile.activities.VideoPlayerActivity
66+
import dev.aaa1115910.bv.mobile.component.videocard.RelatedVideoItem
6367
import dev.aaa1115910.bv.mobile.theme.BVMobileTheme
6468
import dev.aaa1115910.bv.mobile.viewmodel.MobileVideoPlayerViewModel
6569
import dev.aaa1115910.bv.player.mobile.component.BvPlayer
70+
import dev.aaa1115910.bv.util.formatPubTimeString
6671
import kotlinx.coroutines.launch
6772
import org.koin.androidx.compose.koinViewModel
6873

@@ -138,7 +143,7 @@ fun VideoPlayerScreen(
138143

139144
Scaffold { innerPadding ->
140145
Row(
141-
modifier = Modifier.padding(innerPadding)
146+
modifier = Modifier.padding(top = innerPadding.calculateTopPadding())
142147
) {
143148
val leftPartWidth by animateFloatAsState(
144149
targetValue = if (windowSizeClass.widthSizeClass == WindowWidthSizeClass.Expanded && !isVideoFullscreen) 0.6f else 1f,
@@ -214,12 +219,29 @@ fun VideoPlayerScreen(
214219
?: 0,
215220
danmakuCount = playerViewModel.videoDetail?.stat?.danmaku
216221
?: 0,
217-
date = playerViewModel.videoDetail?.publishDate?.toString()
218-
?: "",
222+
date = playerViewModel.videoDetail?.publishDate
223+
?.formatPubTimeString(context) ?: "",
219224
avid = playerViewModel.videoDetail?.aid ?: 0
220225
)
221226
}
222-
RelatedVideos()
227+
items(
228+
items = playerViewModel.videoDetail?.relatedVideos
229+
?: emptyList()
230+
) { relatedVideo ->
231+
RelatedVideoItem(
232+
relatedVideo = relatedVideo,
233+
onClick = {
234+
VideoPlayerActivity.actionStart(
235+
context = context,
236+
aid = relatedVideo.aid,
237+
fromSeason = relatedVideo.jumpToSeason
238+
)
239+
}
240+
)
241+
}
242+
item {
243+
Spacer(modifier = Modifier.navigationBarsPadding())
244+
}
223245
}
224246
}
225247

@@ -243,11 +265,28 @@ fun VideoPlayerScreen(
243265
playCount = playerViewModel.videoDetail?.stat?.view ?: 0,
244266
danmakuCount = playerViewModel.videoDetail?.stat?.danmaku
245267
?: 0,
246-
date = playerViewModel.videoDetail?.publishDate?.toString() ?: "",
268+
date = playerViewModel.videoDetail?.publishDate
269+
?.formatPubTimeString(context) ?: "",
247270
avid = playerViewModel.videoDetail?.aid ?: 0
248271
)
249272
}
250-
RelatedVideos()
273+
items(
274+
items = playerViewModel.videoDetail?.relatedVideos ?: emptyList()
275+
) { relatedVideo ->
276+
RelatedVideoItem(
277+
relatedVideo = relatedVideo,
278+
onClick = {
279+
VideoPlayerActivity.actionStart(
280+
context = context,
281+
aid = relatedVideo.aid,
282+
fromSeason = relatedVideo.jumpToSeason
283+
)
284+
}
285+
)
286+
}
287+
item {
288+
Spacer(modifier = Modifier.navigationBarsPadding())
289+
}
251290
}
252291
}
253292
}
@@ -389,19 +428,6 @@ fun VideoComments(
389428
}
390429
}
391430

392-
fun LazyListScope.RelatedVideos(
393-
) {
394-
repeat(100) {
395-
item {
396-
ListItem(
397-
headlineContent = {
398-
Text(text = "This is a related video #$it")
399-
}
400-
)
401-
}
402-
}
403-
}
404-
405431
@Preview
406432
@Composable
407433
private fun VideoPlayerInfoPreview() {

0 commit comments

Comments
 (0)