mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-02-04 03:36:29 +08:00
feat: Enhance settings screen with section tracking and success notifications; update remote control UI to support localization
This commit is contained in:
@@ -11,6 +11,7 @@ import { APIConfigSection } from "@/components/settings/APIConfigSection";
|
|||||||
import { LiveStreamSection } from "@/components/settings/LiveStreamSection";
|
import { LiveStreamSection } from "@/components/settings/LiveStreamSection";
|
||||||
import { RemoteInputSection } from "@/components/settings/RemoteInputSection";
|
import { RemoteInputSection } from "@/components/settings/RemoteInputSection";
|
||||||
import { VideoSourceSection } from "@/components/settings/VideoSourceSection";
|
import { VideoSourceSection } from "@/components/settings/VideoSourceSection";
|
||||||
|
import Toast from "react-native-toast-message";
|
||||||
|
|
||||||
export default function SettingsScreen() {
|
export default function SettingsScreen() {
|
||||||
const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore();
|
const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore();
|
||||||
@@ -20,6 +21,7 @@ export default function SettingsScreen() {
|
|||||||
const [hasChanges, setHasChanges] = useState(false);
|
const [hasChanges, setHasChanges] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [currentFocusIndex, setCurrentFocusIndex] = useState(0);
|
const [currentFocusIndex, setCurrentFocusIndex] = useState(0);
|
||||||
|
const [currentSection, setCurrentSection] = useState<string | null>(null);
|
||||||
|
|
||||||
const saveButtonRef = useRef<any>(null);
|
const saveButtonRef = useRef<any>(null);
|
||||||
const apiSectionRef = useRef<any>(null);
|
const apiSectionRef = useRef<any>(null);
|
||||||
@@ -39,10 +41,10 @@ export default function SettingsScreen() {
|
|||||||
|
|
||||||
const handleRemoteInput = (message: string) => {
|
const handleRemoteInput = (message: string) => {
|
||||||
// Handle remote input based on currently focused section
|
// Handle remote input based on currently focused section
|
||||||
if (currentFocusIndex === 1 && apiSectionRef.current) {
|
if (currentSection === "api" && apiSectionRef.current) {
|
||||||
// API Config Section
|
// API Config Section
|
||||||
setApiBaseUrl(message);
|
setApiBaseUrl(message);
|
||||||
} else if (currentFocusIndex === 2 && liveStreamSectionRef.current) {
|
} else if (currentSection === "livestream" && liveStreamSectionRef.current) {
|
||||||
// Live Stream Section
|
// Live Stream Section
|
||||||
setM3uUrl(message);
|
setM3uUrl(message);
|
||||||
}
|
}
|
||||||
@@ -53,6 +55,10 @@ export default function SettingsScreen() {
|
|||||||
try {
|
try {
|
||||||
await saveSettings();
|
await saveSettings();
|
||||||
setHasChanges(false);
|
setHasChanges(false);
|
||||||
|
Toast.show({
|
||||||
|
type: "success",
|
||||||
|
text1: "保存成功",
|
||||||
|
});
|
||||||
} catch {
|
} catch {
|
||||||
Alert.alert("错误", "保存设置失败");
|
Alert.alert("错误", "保存设置失败");
|
||||||
} finally {
|
} finally {
|
||||||
@@ -66,12 +72,27 @@ export default function SettingsScreen() {
|
|||||||
|
|
||||||
const sections = [
|
const sections = [
|
||||||
{
|
{
|
||||||
component: <RemoteInputSection onChanged={markAsChanged} onFocus={() => setCurrentFocusIndex(0)} />,
|
component: (
|
||||||
|
<RemoteInputSection
|
||||||
|
onChanged={markAsChanged}
|
||||||
|
onFocus={() => {
|
||||||
|
setCurrentFocusIndex(0);
|
||||||
|
setCurrentSection("remote");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
key: "remote",
|
key: "remote",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: (
|
component: (
|
||||||
<APIConfigSection ref={apiSectionRef} onChanged={markAsChanged} onFocus={() => setCurrentFocusIndex(1)} />
|
<APIConfigSection
|
||||||
|
ref={apiSectionRef}
|
||||||
|
onChanged={markAsChanged}
|
||||||
|
onFocus={() => {
|
||||||
|
setCurrentFocusIndex(1);
|
||||||
|
setCurrentSection("api");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
),
|
),
|
||||||
key: "api",
|
key: "api",
|
||||||
},
|
},
|
||||||
@@ -80,14 +101,25 @@ export default function SettingsScreen() {
|
|||||||
<LiveStreamSection
|
<LiveStreamSection
|
||||||
ref={liveStreamSectionRef}
|
ref={liveStreamSectionRef}
|
||||||
onChanged={markAsChanged}
|
onChanged={markAsChanged}
|
||||||
onFocus={() => setCurrentFocusIndex(2)}
|
onFocus={() => {
|
||||||
|
setCurrentFocusIndex(2);
|
||||||
|
setCurrentSection("livestream");
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: "livestream",
|
key: "livestream",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: <VideoSourceSection onChanged={markAsChanged} onFocus={() => setCurrentFocusIndex(3)} />,
|
component: (
|
||||||
key: "playback",
|
<VideoSourceSection
|
||||||
|
onChanged={markAsChanged}
|
||||||
|
onFocus={() => {
|
||||||
|
setCurrentFocusIndex(3);
|
||||||
|
setCurrentSection("videoSource");
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
key: "videoSource",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,6 @@
|
|||||||
import React, { useCallback, useState } from "react";
|
import React from "react";
|
||||||
import { View, Text, StyleSheet, TouchableOpacity, Pressable } from "react-native";
|
import { View, Text, StyleSheet, Pressable } from "react-native";
|
||||||
import { useRouter } from "expo-router";
|
import { Pause, Play, SkipForward, List, Tv, ArrowDownToDot, ArrowUpFromDot } from "lucide-react-native";
|
||||||
import { AVPlaybackStatus } from "expo-av";
|
|
||||||
import {
|
|
||||||
Pause,
|
|
||||||
Play,
|
|
||||||
SkipForward,
|
|
||||||
List,
|
|
||||||
ChevronsRight,
|
|
||||||
ChevronsLeft,
|
|
||||||
Tv,
|
|
||||||
ArrowDownToDot,
|
|
||||||
ArrowUpFromDot,
|
|
||||||
} from "lucide-react-native";
|
|
||||||
import { ThemedText } from "@/components/ThemedText";
|
import { ThemedText } from "@/components/ThemedText";
|
||||||
import { MediaButton } from "@/components/MediaButton";
|
import { MediaButton } from "@/components/MediaButton";
|
||||||
|
|
||||||
@@ -24,7 +12,6 @@ interface PlayerControlsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const PlayerControls: React.FC<PlayerControlsProps> = ({ showControls, setShowControls }) => {
|
export const PlayerControls: React.FC<PlayerControlsProps> = ({ showControls, setShowControls }) => {
|
||||||
const router = useRouter();
|
|
||||||
const {
|
const {
|
||||||
detail,
|
detail,
|
||||||
currentEpisodeIndex,
|
currentEpisodeIndex,
|
||||||
@@ -33,7 +20,6 @@ export const PlayerControls: React.FC<PlayerControlsProps> = ({ showControls, se
|
|||||||
isSeeking,
|
isSeeking,
|
||||||
seekPosition,
|
seekPosition,
|
||||||
progressPosition,
|
progressPosition,
|
||||||
seek,
|
|
||||||
togglePlayPause,
|
togglePlayPause,
|
||||||
playEpisode,
|
playEpisode,
|
||||||
setShowEpisodeModal,
|
setShowEpisodeModal,
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ const getRemotePageHTML = () => {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="container">
|
<div id="container">
|
||||||
<h3>Send a message to TV</h3>
|
<h3>向电视发送文本</h3>
|
||||||
<input id="text" placeholder="Type here..." />
|
<input id="text" placeholder="请输入..." />
|
||||||
<button onclick="send()">Send</button>
|
<button onclick="send()">发送</button>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|||||||
@@ -183,13 +183,13 @@ export class SearchHistoryManager {
|
|||||||
export class SettingsManager {
|
export class SettingsManager {
|
||||||
static async get(): Promise<AppSettings> {
|
static async get(): Promise<AppSettings> {
|
||||||
const defaultSettings: AppSettings = {
|
const defaultSettings: AppSettings = {
|
||||||
apiBaseUrl: "https://orion-tv.edu.deal",
|
apiBaseUrl: "",
|
||||||
remoteInputEnabled: true,
|
remoteInputEnabled: true,
|
||||||
videoSource: {
|
videoSource: {
|
||||||
enabledAll: true,
|
enabledAll: true,
|
||||||
sources: {},
|
sources: {},
|
||||||
},
|
},
|
||||||
m3uUrl: "https://raw.githubusercontent.com/sjnhnp/adblock/refs/heads/main/filtered_http_only_valid.m3u",
|
m3uUrl: "https://ghfast.top/https://raw.githubusercontent.com/sjnhnp/adblock/refs/heads/main/filtered_http_only_valid.m3u",
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const data = await AsyncStorage.getItem(STORAGE_KEYS.SETTINGS);
|
const data = await AsyncStorage.getItem(STORAGE_KEYS.SETTINGS);
|
||||||
|
|||||||
Reference in New Issue
Block a user