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
+ }
0 commit comments