fix(remote-input): resolve cross-page interference between settings and search pages

- Add targetPage field to remoteControlStore for message routing
- Update settings page to filter messages by target page
- Update search page to filter messages and pass target context
- Add clearMessage method to prevent duplicate message handling
- Ensure remote input only affects intended target page
This commit is contained in:
zimplexing
2025-08-13 17:28:02 +08:00
parent f0c797434d
commit 13fade2113
3 changed files with 26 additions and 15 deletions

View File

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

View File

@@ -22,7 +22,7 @@ import { DeviceUtils } from "@/utils/DeviceUtils";
export default function SettingsScreen() { export default function SettingsScreen() {
const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore(); const { loadSettings, saveSettings, setApiBaseUrl, setM3uUrl } = useSettingsStore();
const { lastMessage } = useRemoteControlStore(); const { lastMessage, targetPage, clearMessage } = useRemoteControlStore();
const backgroundColor = useThemeColor({}, "background"); const backgroundColor = useThemeColor({}, "background");
// 响应式布局配置 // 响应式布局配置
@@ -44,12 +44,13 @@ export default function SettingsScreen() {
}, [loadSettings]); }, [loadSettings]);
useEffect(() => { useEffect(() => {
if (lastMessage) { if (lastMessage && !targetPage) {
const realMessage = lastMessage.split("_")[0]; const realMessage = lastMessage.split("_")[0];
handleRemoteInput(realMessage); handleRemoteInput(realMessage);
clearMessage(); // Clear the message after processing
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [lastMessage]); }, [lastMessage, targetPage]);
const handleRemoteInput = (message: string) => { const handleRemoteInput = (message: string) => {
// Handle remote input based on currently focused section // Handle remote input based on currently focused section

View File

@@ -8,10 +8,12 @@ interface RemoteControlState {
startServer: () => Promise<void>; startServer: () => Promise<void>;
stopServer: () => void; stopServer: () => void;
isModalVisible: boolean; isModalVisible: boolean;
showModal: () => void; showModal: (targetPage?: string) => void;
hideModal: () => void; hideModal: () => void;
lastMessage: string | null; lastMessage: string | null;
setMessage: (message: string) => void; targetPage: string | null;
setMessage: (message: string, targetPage?: string) => void;
clearMessage: () => void;
} }
export const useRemoteControlStore = create<RemoteControlState>((set, get) => ({ export const useRemoteControlStore = create<RemoteControlState>((set, get) => ({
@@ -20,6 +22,7 @@ export const useRemoteControlStore = create<RemoteControlState>((set, get) => ({
error: null, error: null,
isModalVisible: false, isModalVisible: false,
lastMessage: null, lastMessage: null,
targetPage: null,
startServer: async () => { startServer: async () => {
if (get().isServerRunning) { if (get().isServerRunning) {
@@ -28,7 +31,9 @@ export const useRemoteControlStore = create<RemoteControlState>((set, get) => ({
remoteControlService.init({ remoteControlService.init({
onMessage: (message: string) => { onMessage: (message: string) => {
console.log('[RemoteControlStore] Received message:', message); console.log('[RemoteControlStore] Received message:', message);
set({ lastMessage: message }); const currentState = get();
// Use the current targetPage from the store
set({ lastMessage: message, targetPage: currentState.targetPage });
}, },
onHandshake: () => { onHandshake: () => {
console.log('[RemoteControlStore] Handshake successful'); console.log('[RemoteControlStore] Handshake successful');
@@ -53,10 +58,14 @@ export const useRemoteControlStore = create<RemoteControlState>((set, get) => ({
} }
}, },
showModal: () => set({ isModalVisible: true }), showModal: (targetPage?: string) => set({ isModalVisible: true, targetPage }),
hideModal: () => set({ isModalVisible: false }), hideModal: () => set({ isModalVisible: false, targetPage: null }),
setMessage: (message: string) => { setMessage: (message: string, targetPage?: string) => {
set({ lastMessage: `${message}_${Date.now()}` }); set({ lastMessage: `${message}_${Date.now()}`, targetPage });
},
clearMessage: () => {
set({ lastMessage: null, targetPage: null });
}, },
})); }));