mirror of
https://gh-proxy.org/https://github.com/tiajinsha/JKVideo
synced 2026-07-08 07:28:37 +08:00
feat:暗黑模式支持
This commit is contained in:
@@ -75,14 +75,21 @@ export default function VideoDetailScreen() {
|
|||||||
<TouchableOpacity onPress={() => router.back()} style={styles.backBtn}>
|
<TouchableOpacity onPress={() => router.back()} style={styles.backBtn}>
|
||||||
<Ionicons name="chevron-back" size={24} color={theme.text} />
|
<Ionicons name="chevron-back" size={24} color={theme.text} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<Text style={[styles.topTitle, { color: theme.text }]} numberOfLines={1}>
|
<Text
|
||||||
|
style={[styles.topTitle, { color: theme.text }]}
|
||||||
|
numberOfLines={1}
|
||||||
|
>
|
||||||
{video?.title ?? "视频详情"}
|
{video?.title ?? "视频详情"}
|
||||||
</Text>
|
</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.miniBtn}
|
style={styles.miniBtn}
|
||||||
onPress={() => setShowDownload(true)}
|
onPress={() => setShowDownload(true)}
|
||||||
>
|
>
|
||||||
<Ionicons name="cloud-download-outline" size={22} color={theme.text} />
|
<Ionicons
|
||||||
|
name="cloud-download-outline"
|
||||||
|
size={22}
|
||||||
|
color={theme.text}
|
||||||
|
/>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -115,7 +122,11 @@ export default function VideoDetailScreen() {
|
|||||||
onPress={() => setTab("intro")}
|
onPress={() => setTab("intro")}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={[styles.tabLabel, { color: theme.textSub }, tab === "intro" && styles.tabActive]}
|
style={[
|
||||||
|
styles.tabLabel,
|
||||||
|
{ color: theme.textSub },
|
||||||
|
tab === "intro" && styles.tabActive,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
简介
|
简介
|
||||||
</Text>
|
</Text>
|
||||||
@@ -126,7 +137,11 @@ export default function VideoDetailScreen() {
|
|||||||
onPress={() => setTab("comments")}
|
onPress={() => setTab("comments")}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={[styles.tabLabel, { color: theme.textSub }, tab === "comments" && styles.tabActive]}
|
style={[
|
||||||
|
styles.tabLabel,
|
||||||
|
{ color: theme.textSub },
|
||||||
|
tab === "comments" && styles.tabActive,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
评论
|
评论
|
||||||
{video.stat?.reply > 0 ? ` ${formatCount(video.stat.reply)}` : ""}
|
{video.stat?.reply > 0 ? ` ${formatCount(video.stat.reply)}` : ""}
|
||||||
@@ -138,7 +153,11 @@ export default function VideoDetailScreen() {
|
|||||||
onPress={() => setTab("danmaku")}
|
onPress={() => setTab("danmaku")}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={[styles.tabLabel, { color: theme.textSub }, tab === "danmaku" && styles.tabActive]}
|
style={[
|
||||||
|
styles.tabLabel,
|
||||||
|
{ color: theme.textSub },
|
||||||
|
tab === "danmaku" && styles.tabActive,
|
||||||
|
]}
|
||||||
>
|
>
|
||||||
弹幕
|
弹幕
|
||||||
{danmakus.length > 0 ? ` ${formatCount(danmakus.length)}` : ""}
|
{danmakus.length > 0 ? ` ${formatCount(danmakus.length)}` : ""}
|
||||||
@@ -170,13 +189,25 @@ export default function VideoDetailScreen() {
|
|||||||
source={{ uri: proxyImageUrl(video.owner.face) }}
|
source={{ uri: proxyImageUrl(video.owner.face) }}
|
||||||
style={styles.avatar}
|
style={styles.avatar}
|
||||||
/>
|
/>
|
||||||
<Text style={[styles.upName, { color: theme.text }]}>{video.owner.name}</Text>
|
<Text style={[styles.upName, { color: theme.text }]}>
|
||||||
|
{video.owner.name}
|
||||||
|
</Text>
|
||||||
<TouchableOpacity style={styles.followBtn}>
|
<TouchableOpacity style={styles.followBtn}>
|
||||||
<Text style={styles.followTxt}>+ 关注</Text>
|
<Text style={styles.followTxt}>+ 关注</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.titleSection, { borderBottomColor: theme.border }]}>
|
<View
|
||||||
<Text style={[styles.title, { color: theme.text }]}>{video.title}</Text>
|
style={[
|
||||||
|
styles.titleSection,
|
||||||
|
{ borderBottomColor: theme.border },
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text style={[styles.title, { color: theme.text }]}>
|
||||||
|
{video.title}
|
||||||
|
</Text>
|
||||||
|
<Text style={[styles.subTitle, { color: theme.text }]}>
|
||||||
|
{video.desc || "暂无简介"}
|
||||||
|
</Text>
|
||||||
<View style={styles.statsRow}>
|
<View style={styles.statsRow}>
|
||||||
<StatBadge icon="play" count={video.stat.view} />
|
<StatBadge icon="play" count={video.stat.view} />
|
||||||
<StatBadge icon="heart" count={video.stat.like} />
|
<StatBadge icon="heart" count={video.stat.like} />
|
||||||
@@ -193,23 +224,42 @@ export default function VideoDetailScreen() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<View style={styles.descBox}>
|
<View
|
||||||
<Text style={[styles.descText, { color: theme.text }]}>
|
style={[
|
||||||
{video.desc || "暂无简介"}
|
styles.relatedHeader,
|
||||||
|
{
|
||||||
|
backgroundColor: theme.card,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
style={[styles.relatedHeaderText, { color: theme.text }]}
|
||||||
|
>
|
||||||
|
推荐视频
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={[styles.relatedHeader, { backgroundColor: theme.bg, borderTopColor: theme.border }]}>
|
|
||||||
<Text style={[styles.relatedHeaderText, { color: theme.text }]}>推荐视频</Text>
|
|
||||||
</View>
|
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.relatedCard, { backgroundColor: theme.card, borderBottomColor: theme.border }]}
|
style={[
|
||||||
|
styles.relatedCard,
|
||||||
|
{
|
||||||
|
borderTopWidth: StyleSheet.hairlineWidth,
|
||||||
|
borderTopColor: theme.border,
|
||||||
|
backgroundColor: theme.card,
|
||||||
|
borderBottomColor: theme.border,
|
||||||
|
},
|
||||||
|
]}
|
||||||
onPress={() => router.push(`/video/${item.bvid}` as any)}
|
onPress={() => router.push(`/video/${item.bvid}` as any)}
|
||||||
activeOpacity={0.85}
|
activeOpacity={0.85}
|
||||||
>
|
>
|
||||||
<View style={[styles.relatedThumbWrap, { backgroundColor: theme.card }]}>
|
<View
|
||||||
|
style={[
|
||||||
|
styles.relatedThumbWrap,
|
||||||
|
{ backgroundColor: theme.card },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<Image
|
<Image
|
||||||
source={{ uri: proxyImageUrl(item.pic) }}
|
source={{ uri: proxyImageUrl(item.pic) }}
|
||||||
style={styles.relatedThumb}
|
style={styles.relatedThumb}
|
||||||
@@ -222,7 +272,10 @@ export default function VideoDetailScreen() {
|
|||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.relatedInfo}>
|
<View style={styles.relatedInfo}>
|
||||||
<Text style={[styles.relatedTitle, { color: theme.text }]} numberOfLines={2}>
|
<Text
|
||||||
|
style={[styles.relatedTitle, { color: theme.text }]}
|
||||||
|
numberOfLines={2}
|
||||||
|
>
|
||||||
{item.title}
|
{item.title}
|
||||||
</Text>
|
</Text>
|
||||||
<View
|
<View
|
||||||
@@ -267,7 +320,9 @@ export default function VideoDetailScreen() {
|
|||||||
onEndReachedThreshold={0.3}
|
onEndReachedThreshold={0.3}
|
||||||
showsVerticalScrollIndicator={false}
|
showsVerticalScrollIndicator={false}
|
||||||
ListHeaderComponent={
|
ListHeaderComponent={
|
||||||
<View style={[styles.sortRow, { borderBottomColor: theme.border }]}>
|
<View
|
||||||
|
style={[styles.sortRow, { borderBottomColor: theme.border }]}
|
||||||
|
>
|
||||||
<Text style={styles.sortLabel}>排序</Text>
|
<Text style={styles.sortLabel}>排序</Text>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[
|
style={[
|
||||||
@@ -372,9 +427,16 @@ function SeasonSection({
|
|||||||
}, [currentIndex, episodes.length]);
|
}, [currentIndex, episodes.length]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.seasonBox, { borderTopColor: theme.border }]}>
|
<View
|
||||||
|
style={[
|
||||||
|
styles.seasonBox,
|
||||||
|
{ borderTopColor: theme.border, backgroundColor: theme.card },
|
||||||
|
]}
|
||||||
|
>
|
||||||
<View style={styles.seasonHeader}>
|
<View style={styles.seasonHeader}>
|
||||||
<Text style={[styles.seasonTitle, { color: theme.text }]}>合集 · {season.title}</Text>
|
<Text style={[styles.seasonTitle, { color: theme.text }]}>
|
||||||
|
合集 · {season.title}
|
||||||
|
</Text>
|
||||||
<Text style={styles.seasonCount}>{season.ep_count}个视频</Text>
|
<Text style={styles.seasonCount}>{season.ep_count}个视频</Text>
|
||||||
<Ionicons name="chevron-forward" size={14} color="#999" />
|
<Ionicons name="chevron-forward" size={14} color="#999" />
|
||||||
</View>
|
</View>
|
||||||
@@ -395,7 +457,11 @@ function SeasonSection({
|
|||||||
const isCurrent = ep.bvid === currentBvid;
|
const isCurrent = ep.bvid === currentBvid;
|
||||||
return (
|
return (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.epCard, { backgroundColor: theme.bg }, isCurrent && styles.epCardActive]}
|
style={[
|
||||||
|
styles.epCard,
|
||||||
|
{ backgroundColor: theme.card },
|
||||||
|
isCurrent && styles.epCardActive,
|
||||||
|
]}
|
||||||
onPress={() => !isCurrent && onEpisodePress(ep.bvid)}
|
onPress={() => !isCurrent && onEpisodePress(ep.bvid)}
|
||||||
activeOpacity={0.8}
|
activeOpacity={0.8}
|
||||||
>
|
>
|
||||||
@@ -408,7 +474,10 @@ function SeasonSection({
|
|||||||
<Text style={[styles.epNum, isCurrent && styles.epNumActive]}>
|
<Text style={[styles.epNum, isCurrent && styles.epNumActive]}>
|
||||||
第{index + 1}集
|
第{index + 1}集
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={[styles.epTitle, { color: theme.text }]} numberOfLines={2}>
|
<Text
|
||||||
|
style={[styles.epTitle, { color: theme.text }]}
|
||||||
|
numberOfLines={2}
|
||||||
|
>
|
||||||
{ep.title}
|
{ep.title}
|
||||||
</Text>
|
</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
@@ -447,6 +516,10 @@ const styles = StyleSheet.create({
|
|||||||
lineHeight: 22,
|
lineHeight: 22,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
},
|
},
|
||||||
|
subTitle: {
|
||||||
|
fontSize: 10,
|
||||||
|
marginBottom: 8,
|
||||||
|
},
|
||||||
statsRow: { flexDirection: "row", gap: 16 },
|
statsRow: { flexDirection: "row", gap: 16 },
|
||||||
stat: { flexDirection: "row", alignItems: "center", gap: 3 },
|
stat: { flexDirection: "row", alignItems: "center", gap: 3 },
|
||||||
statText: { fontSize: 12, color: "#999" },
|
statText: { fontSize: 12, color: "#999" },
|
||||||
@@ -522,9 +595,9 @@ const styles = StyleSheet.create({
|
|||||||
danmakuTab: { flex: 1 },
|
danmakuTab: { flex: 1 },
|
||||||
emptyTxt: { textAlign: "center", color: "#bbb", padding: 30 },
|
emptyTxt: { textAlign: "center", color: "#bbb", padding: 30 },
|
||||||
relatedHeader: {
|
relatedHeader: {
|
||||||
paddingHorizontal: 14,
|
paddingLeft: 12,
|
||||||
paddingVertical: 10,
|
paddingBottom: 8,
|
||||||
borderTopWidth: StyleSheet.hairlineWidth,
|
paddingTop: 8,
|
||||||
},
|
},
|
||||||
relatedHeaderText: {
|
relatedHeaderText: {
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export function FollowedLiveStrip() {
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
backgroundColor: "#f4f4f4",
|
backgroundColor: "#f4f4f4",
|
||||||
paddingHorizontal: 12,
|
paddingHorizontal: 3,
|
||||||
paddingVertical: 8,
|
paddingVertical: 8,
|
||||||
},
|
},
|
||||||
scrollContent: {
|
scrollContent: {
|
||||||
|
|||||||
Reference in New Issue
Block a user