mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-14 13:26:22 +00:00
Compare commits
1 Commits
feat/tv-in
...
feat/tv-in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8c21054d33 |
@@ -144,11 +144,11 @@ export const Button: React.FC<PropsWithChildren<ButtonProps>> = ({
|
|||||||
className={`rounded-2xl items-center justify-center
|
className={`rounded-2xl items-center justify-center
|
||||||
${colorClasses}
|
${colorClasses}
|
||||||
${className}`}
|
${className}`}
|
||||||
style={{ paddingVertical: size(20) }}
|
style={{ paddingVertical: size(50) }}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
className={`${textColorClass} font-bold`}
|
className={`${textColorClass} font-bold`}
|
||||||
style={{ fontSize: fontSize(20) }}
|
style={{ fontSize: fontSize(10) }}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
|
|||||||
@@ -601,10 +601,10 @@ export const TVLogin: React.FC = () => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Logo */}
|
{/* Logo */}
|
||||||
<View style={{ alignItems: "center", marginBottom: size(16) }}>
|
<View style={{ alignItems: "center", marginBottom: size(5) }}>
|
||||||
<Image
|
<Image
|
||||||
source={require("@/assets/images/icon-tvos.png")}
|
source={require("@/assets/images/icon-tvos.png")}
|
||||||
style={{ width: size(300), height: size(300) }}
|
style={{ width: size(400), height: size(400) }}
|
||||||
contentFit='contain'
|
contentFit='contain'
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
@@ -623,7 +623,7 @@ export const TVLogin: React.FC = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: fontSize(20),
|
fontSize: fontSize(10),
|
||||||
color: "#9CA3AF",
|
color: "#9CA3AF",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
marginBottom: size(40),
|
marginBottom: size(40),
|
||||||
@@ -634,7 +634,7 @@ export const TVLogin: React.FC = () => {
|
|||||||
|
|
||||||
{/* Server URL Input - extra padding for focus scale */}
|
{/* Server URL Input - extra padding for focus scale */}
|
||||||
<View
|
<View
|
||||||
style={{ marginBottom: size(24), paddingHorizontal: size(8) }}
|
style={{ marginBottom: size(50), paddingHorizontal: size(300) }}
|
||||||
>
|
>
|
||||||
<TVInput
|
<TVInput
|
||||||
placeholder={t("server.server_url_placeholder")}
|
placeholder={t("server.server_url_placeholder")}
|
||||||
@@ -650,7 +650,9 @@ export const TVLogin: React.FC = () => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Connect Button */}
|
{/* Connect Button */}
|
||||||
<View style={{ marginBottom: size(12) }}>
|
<View
|
||||||
|
style={{ marginBottom: size(12), paddingHorizontal: size(270) }}
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
onPress={() => handleConnect(serverURL)}
|
onPress={() => handleConnect(serverURL)}
|
||||||
loading={loadingServerCheck}
|
loading={loadingServerCheck}
|
||||||
@@ -661,7 +663,7 @@ export const TVLogin: React.FC = () => {
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{/* Previous Servers */}
|
{/* Previous Servers */}
|
||||||
<View style={{ paddingHorizontal: size(8) }}>
|
<View style={{ paddingHorizontal: size(300) }}>
|
||||||
<TVPreviousServersList
|
<TVPreviousServersList
|
||||||
onServerSelect={(s) => handleConnect(s.address)}
|
onServerSelect={(s) => handleConnect(s.address)}
|
||||||
onQuickLogin={handleQuickLoginWithSavedCredential}
|
onQuickLogin={handleQuickLoginWithSavedCredential}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { useMMKVString } from "react-native-mmkv";
|
import { useMMKVString } from "react-native-mmkv";
|
||||||
|
import { fontSize, height, size, width } from "react-native-responsive-sizes";
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { Text } from "@/components/common/Text";
|
import { Text } from "@/components/common/Text";
|
||||||
import {
|
import {
|
||||||
@@ -61,8 +62,8 @@ const TVServerActionCard: React.FC<{
|
|||||||
<Animated.View
|
<Animated.View
|
||||||
style={{
|
style={{
|
||||||
transform: [{ scale }],
|
transform: [{ scale }],
|
||||||
width: 180,
|
width: width(25),
|
||||||
height: 90,
|
height: height(15),
|
||||||
backgroundColor: focused
|
backgroundColor: focused
|
||||||
? isDestructive
|
? isDestructive
|
||||||
? "#ef4444"
|
? "#ef4444"
|
||||||
@@ -70,16 +71,16 @@ const TVServerActionCard: React.FC<{
|
|||||||
: isDestructive
|
: isDestructive
|
||||||
? "rgba(239, 68, 68, 0.2)"
|
? "rgba(239, 68, 68, 0.2)"
|
||||||
: "rgba(255,255,255,0.08)",
|
: "rgba(255,255,255,0.08)",
|
||||||
borderRadius: 14,
|
borderRadius: size(20),
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
paddingHorizontal: 12,
|
paddingHorizontal: size(12),
|
||||||
gap: 8,
|
gap: size(8),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name={icon}
|
name={icon}
|
||||||
size={28}
|
size={size(56)}
|
||||||
color={
|
color={
|
||||||
focused
|
focused
|
||||||
? isDestructive
|
? isDestructive
|
||||||
@@ -92,7 +93,7 @@ const TVServerActionCard: React.FC<{
|
|||||||
/>
|
/>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 16,
|
fontSize: fontSize(12),
|
||||||
color: focused
|
color: focused
|
||||||
? isDestructive
|
? isDestructive
|
||||||
? "#fff"
|
? "#fff"
|
||||||
@@ -142,26 +143,26 @@ const TVServerActionSheet: React.FC<{
|
|||||||
intensity={80}
|
intensity={80}
|
||||||
tint='dark'
|
tint='dark'
|
||||||
style={{
|
style={{
|
||||||
borderTopLeftRadius: 24,
|
borderTopLeftRadius: size(24),
|
||||||
borderTopRightRadius: 24,
|
borderTopRightRadius: size(24),
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
paddingTop: 24,
|
paddingTop: size(24),
|
||||||
paddingBottom: 50,
|
paddingBottom: size(50),
|
||||||
overflow: "visible",
|
overflow: "visible",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Title */}
|
{/* Title */}
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 18,
|
fontSize: fontSize(12),
|
||||||
fontWeight: "500",
|
fontWeight: "500",
|
||||||
color: "rgba(255,255,255,0.6)",
|
color: "rgba(255,255,255,0.6)",
|
||||||
marginBottom: 8,
|
marginBottom: size(12),
|
||||||
paddingHorizontal: 48,
|
paddingHorizontal: size(48),
|
||||||
textTransform: "uppercase",
|
textTransform: "uppercase",
|
||||||
letterSpacing: 1,
|
letterSpacing: 1,
|
||||||
}}
|
}}
|
||||||
@@ -175,9 +176,9 @@ const TVServerActionSheet: React.FC<{
|
|||||||
showsHorizontalScrollIndicator={false}
|
showsHorizontalScrollIndicator={false}
|
||||||
style={{ overflow: "visible" }}
|
style={{ overflow: "visible" }}
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
paddingHorizontal: 48,
|
paddingHorizontal: size(48),
|
||||||
paddingVertical: 10,
|
paddingVertical: size(10),
|
||||||
gap: 12,
|
gap: size(12),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<TVServerActionCard
|
<TVServerActionCard
|
||||||
@@ -398,19 +399,19 @@ export const TVPreviousServersList: React.FC<TVPreviousServersListProps> = ({
|
|||||||
if (!previousServers.length) return null;
|
if (!previousServers.length) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ marginTop: 32 }}>
|
<View style={{ marginTop: size(100) }}>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 24,
|
fontSize: fontSize(12),
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
marginBottom: 16,
|
marginBottom: size(20),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t("server.previous_servers")}
|
{t("server.previous_servers")}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<View style={{ gap: 12 }}>
|
<View style={{ gap: size(12) }}>
|
||||||
{previousServers.map((server) => (
|
{previousServers.map((server) => (
|
||||||
<TVServerCard
|
<TVServerCard
|
||||||
key={server.address}
|
key={server.address}
|
||||||
@@ -437,39 +438,39 @@ export const TVPreviousServersList: React.FC<TVPreviousServersListProps> = ({
|
|||||||
backgroundColor: "rgba(0, 0, 0, 0.9)",
|
backgroundColor: "rgba(0, 0, 0, 0.9)",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
padding: 80,
|
padding: size(80),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: "#1a1a1a",
|
backgroundColor: "#1a1a1a",
|
||||||
borderRadius: 24,
|
borderRadius: size(24),
|
||||||
padding: 40,
|
padding: size(40),
|
||||||
width: "100%",
|
width: "100%",
|
||||||
maxWidth: 700,
|
maxWidth: width(70),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 32,
|
fontSize: fontSize(32),
|
||||||
fontWeight: "bold",
|
fontWeight: "bold",
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
marginBottom: 8,
|
marginBottom: size(8),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t("server.select_account")}
|
{t("server.select_account")}
|
||||||
</Text>
|
</Text>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 18,
|
fontSize: fontSize(18),
|
||||||
color: "#9CA3AF",
|
color: "#9CA3AF",
|
||||||
marginBottom: 32,
|
marginBottom: size(32),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{selectedServer?.name || selectedServer?.address}
|
{selectedServer?.name || selectedServer?.address}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<View style={{ gap: 12, marginBottom: 24 }}>
|
<View style={{ gap: size(12), marginBottom: size(24) }}>
|
||||||
{selectedServer?.accounts.map((account, index) => (
|
{selectedServer?.accounts.map((account, index) => (
|
||||||
<TVAccountCard
|
<TVAccountCard
|
||||||
key={account.userId}
|
key={account.userId}
|
||||||
@@ -484,7 +485,7 @@ export const TVPreviousServersList: React.FC<TVPreviousServersListProps> = ({
|
|||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ gap: 12 }}>
|
<View style={{ gap: size(12) }}>
|
||||||
<Button
|
<Button
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
setShowAccountsModal(false);
|
setShowAccountsModal(false);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Pressable,
|
Pressable,
|
||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
|
import { fontSize, size } from "react-native-responsive-sizes";
|
||||||
import { Text } from "@/components/common/Text";
|
import { Text } from "@/components/common/Text";
|
||||||
import { Colors } from "@/constants/Colors";
|
import { Colors } from "@/constants/Colors";
|
||||||
|
|
||||||
@@ -86,11 +87,11 @@ export const TVServerCard: React.FC<TVServerCardProps> = ({
|
|||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: isFocused ? "#2a2a2a" : "#1a1a1a",
|
backgroundColor: isFocused ? "#2a2a2a" : "#1a1a1a",
|
||||||
borderWidth: 2,
|
borderWidth: size(6),
|
||||||
borderColor: isFocused ? "#FFFFFF" : "transparent",
|
borderColor: isFocused ? "#FFFFFF" : "transparent",
|
||||||
borderRadius: 16,
|
borderRadius: size(50),
|
||||||
paddingHorizontal: 24,
|
paddingHorizontal: size(50),
|
||||||
paddingVertical: 20,
|
paddingVertical: size(40),
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
@@ -99,7 +100,7 @@ export const TVServerCard: React.FC<TVServerCardProps> = ({
|
|||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 22,
|
fontSize: fontSize(12),
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
color: "#FFFFFF",
|
color: "#FFFFFF",
|
||||||
}}
|
}}
|
||||||
@@ -110,9 +111,9 @@ export const TVServerCard: React.FC<TVServerCardProps> = ({
|
|||||||
{subtitle && (
|
{subtitle && (
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 16,
|
fontSize: fontSize(10),
|
||||||
color: "#9CA3AF",
|
color: "#9CA3AF",
|
||||||
marginTop: 4,
|
marginTop: size(12),
|
||||||
}}
|
}}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
>
|
>
|
||||||
@@ -121,27 +122,27 @@ export const TVServerCard: React.FC<TVServerCardProps> = ({
|
|||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={{ marginLeft: 16 }}>
|
<View style={{ marginLeft: size(16) }}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<ActivityIndicator size='small' color={Colors.primary} />
|
<ActivityIndicator size='small' color={Colors.primary} />
|
||||||
) : securityIcon ? (
|
) : securityIcon ? (
|
||||||
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
<View style={{ flexDirection: "row", alignItems: "center" }}>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name={securityIcon}
|
name={securityIcon}
|
||||||
size={20}
|
size={size(60)}
|
||||||
color={Colors.primary}
|
color={Colors.primary}
|
||||||
style={{ marginRight: 8 }}
|
style={{ marginRight: size(16) }}
|
||||||
/>
|
/>
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name='chevron-forward'
|
name='chevron-forward'
|
||||||
size={24}
|
size={size(48)}
|
||||||
color={isFocused ? "#FFFFFF" : "#6B7280"}
|
color={isFocused ? "#FFFFFF" : "#6B7280"}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<Ionicons
|
<Ionicons
|
||||||
name='chevron-forward'
|
name='chevron-forward'
|
||||||
size={24}
|
size={size(48)}
|
||||||
color={isFocused ? "#FFFFFF" : "#6B7280"}
|
color={isFocused ? "#FFFFFF" : "#6B7280"}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user