Merge branch 'v1.3.0' of github.com:zimplexing/OrionTV into v1.3.0

This commit is contained in:
zimplexing
2025-08-13 18:47:48 +08:00
9 changed files with 270 additions and 246 deletions

View File

@@ -128,7 +128,7 @@ export default function HomeScreen() {
// TV端和平板端的顶部导航
const renderHeader = () => {
if (deviceType === 'mobile') {
if (deviceType === "mobile") {
// 移动端不显示顶部导航使用底部Tab导航
return null;
}
@@ -171,7 +171,7 @@ export default function HomeScreen() {
const dynamicStyles = StyleSheet.create({
container: {
flex: 1,
paddingTop: deviceType === 'mobile' ? insets.top : 40,
paddingTop: deviceType === "mobile" ? 0 : 40,
},
headerContainer: {
flexDirection: "row",
@@ -181,7 +181,7 @@ export default function HomeScreen() {
marginBottom: spacing,
},
headerTitle: {
fontSize: deviceType === 'mobile' ? 24 : deviceType === 'tablet' ? 28 : 32,
fontSize: deviceType === "mobile" ? 24 : deviceType === "tablet" ? 28 : 32,
fontWeight: "bold",
paddingTop: 16,
},
@@ -200,13 +200,13 @@ export default function HomeScreen() {
paddingHorizontal: spacing,
},
categoryButton: {
paddingHorizontal: deviceType === 'tv' ? spacing / 4 : spacing / 2,
paddingVertical: deviceType === 'tv' ? spacing / 4 : spacing / 2,
borderRadius: deviceType === 'mobile' ? 6 : 8,
marginHorizontal: deviceType === 'tv' ? spacing / 4 : spacing / 2,
paddingHorizontal: deviceType === "tv" ? spacing / 4 : spacing / 2,
paddingVertical: spacing / 2,
borderRadius: deviceType === "mobile" ? 6 : 8,
marginHorizontal: deviceType === "tv" ? spacing / 4 : spacing / 2, // TV端使用更小的间距
},
categoryText: {
fontSize: deviceType === 'mobile' ? 14 : 16,
fontSize: deviceType === "mobile" ? 14 : 16,
fontWeight: "500",
},
contentContainer: {
@@ -217,8 +217,8 @@ export default function HomeScreen() {
const content = (
<ThemedView style={[commonStyles.container, dynamicStyles.container]}>
{/* 状态栏 */}
{deviceType === 'mobile' && <StatusBar barStyle="light-content" />}
{deviceType === "mobile" && <StatusBar barStyle="light-content" />}
{/* 顶部导航 */}
{renderHeader()}
@@ -291,13 +291,9 @@ export default function HomeScreen() {
);
// 根据设备类型决定是否包装在响应式导航中
if (deviceType === 'tv') {
if (deviceType === "tv") {
return content;
}
return (
<ResponsiveNavigation>
{content}
</ResponsiveNavigation>
);
}
return <ResponsiveNavigation>{content}</ResponsiveNavigation>;
}

View File

@@ -26,7 +26,7 @@ export default function SearchScreen() {
const [error, setError] = useState<string | null>(null);
const textInputRef = useRef<TextInput>(null);
const [isInputFocused, setIsInputFocused] = useState(false);
const { showModal: showRemoteModal, lastMessage } = useRemoteControlStore();
const { showModal: showRemoteModal, lastMessage, targetPage, clearMessage } = useRemoteControlStore();
const { remoteInputEnabled } = useSettingsStore();
const router = useRouter();
@@ -36,14 +36,15 @@ export default function SearchScreen() {
const { deviceType, spacing } = responsiveConfig;
useEffect(() => {
if (lastMessage) {
if (lastMessage && targetPage === 'search') {
console.log("Received remote input:", lastMessage);
const realMessage = lastMessage.split("_")[0];
setKeyword(realMessage);
handleSearch(realMessage);
clearMessage(); // Clear the message after processing
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lastMessage]);
}, [lastMessage, targetPage]);
// useEffect(() => {
// // Focus the text input when the screen loads
@@ -87,10 +88,10 @@ export default function SearchScreen() {
]);
return;
}
showRemoteModal();
showRemoteModal('search');
};
const renderItem = ({ item, index }: { item: SearchResult; index: number }) => (
const renderItem = ({ item }: { item: SearchResult; index: number }) => (
<VideoCard
id={item.id.toString()}
source={item.source}

View File

@@ -22,7 +22,7 @@ import { DeviceUtils } from "@/utils/DeviceUtils";
export default function SettingsScreen() {
const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore();
const { lastMessage } = useRemoteControlStore();
const { lastMessage, targetPage, clearMessage } = useRemoteControlStore();
const backgroundColor = useThemeColor({}, "background");
// 响应式布局配置
@@ -44,12 +44,13 @@ export default function SettingsScreen() {
}, [loadSettings]);
useEffect(() => {
if (lastMessage) {
if (lastMessage && !targetPage) {
const realMessage = lastMessage.split("_")[0];
handleRemoteInput(realMessage);
clearMessage(); // Clear the message after processing
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lastMessage]);
}, [lastMessage, targetPage]);
const handleRemoteInput = (message: string) => {
// Handle remote input based on currently focused section
@@ -133,10 +134,8 @@ export default function SettingsScreen() {
// ),
// key: "videoSource",
// },
Platform.OS === 'android' && {
component: (
<UpdateSection />
),
Platform.OS === "android" && {
component: <UpdateSection />,
key: "update",
},
].filter(Boolean);
@@ -144,8 +143,8 @@ export default function SettingsScreen() {
// TV遥控器事件处理 - 仅在TV设备上启用
const handleTVEvent = React.useCallback(
(event: any) => {
if (deviceType !== 'tv') return;
if (deviceType !== "tv") return;
if (event.eventType === "down") {
const nextIndex = Math.min(currentFocusIndex + 1, sections.length);
setCurrentFocusIndex(nextIndex);
@@ -160,18 +159,15 @@ export default function SettingsScreen() {
[currentFocusIndex, sections.length, deviceType]
);
useTVEventHandler(deviceType === 'tv' ? handleTVEvent : () => {});
useTVEventHandler(deviceType === "tv" ? handleTVEvent : () => {});
// 动态样式
const dynamicStyles = createResponsiveStyles(deviceType, spacing);
const renderSettingsContent = () => (
<KeyboardAvoidingView
style={{ flex: 1, backgroundColor }}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<KeyboardAvoidingView style={{ flex: 1, backgroundColor }} behavior={Platform.OS === "ios" ? "padding" : "height"}>
<ThemedView style={[commonStyles.container, dynamicStyles.container]}>
{deviceType === 'tv' && (
{deviceType === "tv" && (
<View style={dynamicStyles.header}>
<ThemedText style={dynamicStyles.title}></ThemedText>
</View>
@@ -186,7 +182,7 @@ export default function SettingsScreen() {
}
return null;
}}
keyExtractor={(item) => item ? item.key : 'default'}
keyExtractor={(item) => (item ? item.key : "default")}
showsVerticalScrollIndicator={false}
contentContainerStyle={dynamicStyles.listContent}
/>
@@ -198,10 +194,7 @@ export default function SettingsScreen() {
onPress={handleSave}
variant="primary"
disabled={!hasChanges || isLoading}
style={[
dynamicStyles.saveButton,
(!hasChanges || isLoading) && dynamicStyles.disabledButton
]}
style={[dynamicStyles.saveButton, (!hasChanges || isLoading) && dynamicStyles.disabledButton]}
/>
</View>
</ThemedView>
@@ -209,7 +202,7 @@ export default function SettingsScreen() {
);
// 根据设备类型决定是否包装在响应式导航中
if (deviceType === 'tv') {
if (deviceType === "tv") {
return renderSettingsContent();
}
@@ -222,9 +215,9 @@ export default function SettingsScreen() {
}
const createResponsiveStyles = (deviceType: string, spacing: number) => {
const isMobile = deviceType === 'mobile';
const isTablet = deviceType === 'tablet';
const isTV = deviceType === 'tv';
const isMobile = deviceType === "mobile";
const isTablet = deviceType === "tablet";
const isTV = deviceType === "tv";
const minTouchTarget = DeviceUtils.getMinTouchTargetSize();
return StyleSheet.create({
@@ -243,7 +236,7 @@ const createResponsiveStyles = (deviceType: string, spacing: number) => {
fontSize: isMobile ? 24 : isTablet ? 28 : 32,
fontWeight: "bold",
paddingTop: spacing,
color: 'white',
color: "white",
},
scrollView: {
flex: 1,
@@ -257,7 +250,7 @@ const createResponsiveStyles = (deviceType: string, spacing: number) => {
},
saveButton: {
minHeight: isMobile ? minTouchTarget : isTablet ? 50 : 50,
width: isMobile ? '100%' : isTablet ? 140 : 120,
width: isMobile ? "100%" : isTablet ? 140 : 120,
maxWidth: isMobile ? 280 : undefined,
},
disabledButton: {