mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-28 22:18:14 +00:00
135 lines
3.0 KiB
TypeScript
135 lines
3.0 KiB
TypeScript
import { BlurView } from "expo-blur";
|
|
import { Platform, StyleSheet, View, type ViewProps } from "react-native";
|
|
import { GlassEffectView } from "react-native-glass-effect-view";
|
|
import { useScaledTVTypography } from "@/constants/TVTypography";
|
|
import { Text } from "./common/Text";
|
|
|
|
interface Props extends ViewProps {
|
|
text?: string | number | null;
|
|
variant?: "gray" | "purple";
|
|
iconLeft?: React.ReactNode;
|
|
}
|
|
|
|
export const Badge: React.FC<Props> = ({
|
|
iconLeft,
|
|
text,
|
|
variant = "purple",
|
|
...props
|
|
}) => {
|
|
const typography = useScaledTVTypography();
|
|
|
|
const content = (
|
|
<View style={styles.content}>
|
|
{iconLeft && <View style={styles.iconLeft}>{iconLeft}</View>}
|
|
<Text
|
|
className={`
|
|
text-xs
|
|
${variant === "purple" && "text-white"}
|
|
`}
|
|
>
|
|
{text}
|
|
</Text>
|
|
</View>
|
|
);
|
|
|
|
if (Platform.OS === "ios" && !Platform.isTV) {
|
|
return (
|
|
<View {...props} style={[styles.container, props.style]}>
|
|
<GlassEffectView style={{ borderRadius: 100 }}>
|
|
{content}
|
|
</GlassEffectView>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
// On TV, use BlurView for consistent styling
|
|
if (Platform.isTV) {
|
|
return (
|
|
<BlurView
|
|
intensity={10}
|
|
tint='light'
|
|
style={{
|
|
borderRadius: 8,
|
|
overflow: "hidden",
|
|
alignSelf: "flex-start",
|
|
flexShrink: 1,
|
|
flexGrow: 0,
|
|
}}
|
|
>
|
|
<View
|
|
style={[
|
|
{
|
|
paddingVertical: 10,
|
|
paddingHorizontal: 16,
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
backgroundColor: "rgba(0,0,0,0.3)",
|
|
},
|
|
props.style,
|
|
]}
|
|
>
|
|
{iconLeft && <View style={{ marginRight: 8 }}>{iconLeft}</View>}
|
|
<Text
|
|
style={{
|
|
fontSize: typography.callout,
|
|
color: "#E5E7EB",
|
|
}}
|
|
>
|
|
{text}
|
|
</Text>
|
|
</View>
|
|
</BlurView>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View
|
|
{...props}
|
|
style={[
|
|
{
|
|
borderRadius: 4,
|
|
padding: 4,
|
|
paddingHorizontal: 6,
|
|
flexShrink: 1,
|
|
flexGrow: 0,
|
|
alignSelf: "flex-start",
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
backgroundColor: variant === "purple" ? "#9333ea" : "#262626",
|
|
},
|
|
props.style,
|
|
]}
|
|
>
|
|
{iconLeft && <View style={{ marginRight: 4 }}>{iconLeft}</View>}
|
|
<Text
|
|
style={{
|
|
fontSize: 12,
|
|
color: "#fff",
|
|
}}
|
|
>
|
|
{text}
|
|
</Text>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
overflow: "hidden",
|
|
alignSelf: "flex-start",
|
|
flexShrink: 1,
|
|
flexGrow: 0,
|
|
},
|
|
content: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
paddingHorizontal: 10,
|
|
paddingVertical: 4,
|
|
borderRadius: 50,
|
|
backgroundColor: "transparent",
|
|
},
|
|
iconLeft: {
|
|
marginRight: 4,
|
|
},
|
|
});
|