mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 00:32:04 +00:00
Enhance Search tab behavior with event emitter
Added DeviceEventEmitter to handle search input focus on tab press for Search tab.
This commit is contained in:
parent
56df30a4da
commit
066bf6f15d
1 changed files with 74 additions and 7 deletions
|
|
@ -2,7 +2,7 @@ import React, { useEffect, useRef, useMemo, useState } from 'react';
|
||||||
import { NavigationContainer, DefaultTheme as NavigationDefaultTheme, DarkTheme as NavigationDarkTheme, Theme, NavigationProp } from '@react-navigation/native';
|
import { NavigationContainer, DefaultTheme as NavigationDefaultTheme, DarkTheme as NavigationDarkTheme, Theme, NavigationProp } from '@react-navigation/native';
|
||||||
import { createNativeStackNavigator, NativeStackNavigationOptions, NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import { createNativeStackNavigator, NativeStackNavigationOptions, NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import { createBottomTabNavigator, BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
|
import { createBottomTabNavigator, BottomTabNavigationProp } from '@react-navigation/bottom-tabs';
|
||||||
import { useColorScheme, Platform, Animated, StatusBar, TouchableOpacity, View, Text, AppState, Easing, Dimensions } from 'react-native';
|
import { useColorScheme, Platform, Animated, StatusBar, TouchableOpacity, View, Text, AppState, Easing, Dimensions, DeviceEventEmitter } from 'react-native';
|
||||||
import { mmkvStorage } from '../services/mmkvStorage';
|
import { mmkvStorage } from '../services/mmkvStorage';
|
||||||
import { PaperProvider, MD3DarkTheme, MD3LightTheme, adaptNavigationTheme } from 'react-native-paper';
|
import { PaperProvider, MD3DarkTheme, MD3LightTheme, adaptNavigationTheme } from 'react-native-paper';
|
||||||
import type { MD3Theme } from 'react-native-paper';
|
import type { MD3Theme } from 'react-native-paper';
|
||||||
|
|
@ -71,6 +71,7 @@ import BackupScreen from '../screens/BackupScreen';
|
||||||
import ContinueWatchingSettingsScreen from '../screens/ContinueWatchingSettingsScreen';
|
import ContinueWatchingSettingsScreen from '../screens/ContinueWatchingSettingsScreen';
|
||||||
import ContributorsScreen from '../screens/ContributorsScreen';
|
import ContributorsScreen from '../screens/ContributorsScreen';
|
||||||
import DebridIntegrationScreen from '../screens/DebridIntegrationScreen';
|
import DebridIntegrationScreen from '../screens/DebridIntegrationScreen';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentDiscoverySettingsScreen,
|
ContentDiscoverySettingsScreen,
|
||||||
AppearanceSettingsScreen,
|
AppearanceSettingsScreen,
|
||||||
|
|
@ -689,15 +690,32 @@ const MainTabs = () => {
|
||||||
const isFocused = props.state.index === index;
|
const isFocused = props.state.index === index;
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
|
// Create a synthetic event object we can modify
|
||||||
|
const syntheticEvent = {
|
||||||
|
type: 'tabPress',
|
||||||
|
target: route.key,
|
||||||
|
canPreventDefault: true,
|
||||||
|
defaultPrevented: false,
|
||||||
|
preventDefault: () => {
|
||||||
|
syntheticEvent.defaultPrevented = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const event = props.navigation.emit({
|
const event = props.navigation.emit({
|
||||||
type: 'tabPress',
|
type: 'tabPress',
|
||||||
target: route.key,
|
target: route.key,
|
||||||
canPreventDefault: true,
|
canPreventDefault: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
// Same tab pressed - emit scroll to top
|
if (route.name === 'Search') {
|
||||||
emitScrollToTop(route.name);
|
// Send the signal to SearchScreen.tsx to focus input
|
||||||
} else if (!event.defaultPrevented) {
|
DeviceEventEmitter.emit('FOCUS_SEARCH_INPUT');
|
||||||
|
syntheticEvent.preventDefault(); // Prevent scroll-to-top
|
||||||
|
} else {
|
||||||
|
emitScrollToTop(route.name);
|
||||||
|
}
|
||||||
|
} else if (!syntheticEvent.defaultPrevented && !event.defaultPrevented) {
|
||||||
props.navigation.navigate(route.name);
|
props.navigation.navigate(route.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -806,6 +824,14 @@ const MainTabs = () => {
|
||||||
const isFocused = props.state.index === index;
|
const isFocused = props.state.index === index;
|
||||||
|
|
||||||
const onPress = () => {
|
const onPress = () => {
|
||||||
|
// For Search tab, we need to handle this specially
|
||||||
|
if (isFocused && route.name === 'Search') {
|
||||||
|
// Focus search input instead of scrolling to top
|
||||||
|
DeviceEventEmitter.emit('FOCUS_SEARCH_INPUT');
|
||||||
|
// Return early to prevent navigation and scroll-to-top
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const event = props.navigation.emit({
|
const event = props.navigation.emit({
|
||||||
type: 'tabPress',
|
type: 'tabPress',
|
||||||
target: route.key,
|
target: route.key,
|
||||||
|
|
@ -813,7 +839,7 @@ const MainTabs = () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isFocused) {
|
if (isFocused) {
|
||||||
// Same tab pressed - emit scroll to top
|
// For other tabs, scroll to top
|
||||||
emitScrollToTop(route.name);
|
emitScrollToTop(route.name);
|
||||||
} else if (!event.defaultPrevented) {
|
} else if (!event.defaultPrevented) {
|
||||||
props.navigation.navigate(route.name);
|
props.navigation.navigate(route.name);
|
||||||
|
|
@ -952,7 +978,10 @@ const MainTabs = () => {
|
||||||
listeners={({ navigation }: { navigation: any }) => ({
|
listeners={({ navigation }: { navigation: any }) => ({
|
||||||
tabPress: (e: any) => {
|
tabPress: (e: any) => {
|
||||||
if (navigation.isFocused()) {
|
if (navigation.isFocused()) {
|
||||||
emitScrollToTop('Search');
|
// Focus search input instead of scrolling to top
|
||||||
|
DeviceEventEmitter.emit('FOCUS_SEARCH_INPUT');
|
||||||
|
// Don't try to access preventDefault on native iOS tabs
|
||||||
|
// Just emit the event and let SearchScreen handle it
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
|
|
@ -1059,6 +1088,13 @@ const MainTabs = () => {
|
||||||
),
|
),
|
||||||
freezeOnBlur: true,
|
freezeOnBlur: true,
|
||||||
}}
|
}}
|
||||||
|
listeners={({ navigation }: any) => ({
|
||||||
|
tabPress: (e: any) => {
|
||||||
|
if (navigation.isFocused()) {
|
||||||
|
emitScrollToTop('Home');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Library"
|
name="Library"
|
||||||
|
|
@ -1069,6 +1105,13 @@ const MainTabs = () => {
|
||||||
<MaterialCommunityIcons name={focused ? 'heart' : 'heart-outline'} size={size} color={color} />
|
<MaterialCommunityIcons name={focused ? 'heart' : 'heart-outline'} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
listeners={({ navigation }: any) => ({
|
||||||
|
tabPress: (e: any) => {
|
||||||
|
if (navigation.isFocused()) {
|
||||||
|
emitScrollToTop('Library');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="Search"
|
name="Search"
|
||||||
|
|
@ -1079,6 +1122,16 @@ const MainTabs = () => {
|
||||||
<MaterialCommunityIcons name={'magnify'} size={size} color={color} />
|
<MaterialCommunityIcons name={'magnify'} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
listeners={({ navigation }: any) => ({
|
||||||
|
tabPress: (e: any) => {
|
||||||
|
if (navigation.isFocused()) {
|
||||||
|
// Focus search input instead of scrolling to top
|
||||||
|
DeviceEventEmitter.emit('FOCUS_SEARCH_INPUT');
|
||||||
|
// Simply return to prevent navigation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
{appSettings?.enableDownloads !== false && (
|
{appSettings?.enableDownloads !== false && (
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
|
|
@ -1090,6 +1143,13 @@ const MainTabs = () => {
|
||||||
<MaterialCommunityIcons name={focused ? 'download' : 'download-outline'} size={size} color={color} />
|
<MaterialCommunityIcons name={focused ? 'download' : 'download-outline'} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
listeners={({ navigation }: any) => ({
|
||||||
|
tabPress: (e: any) => {
|
||||||
|
if (navigation.isFocused()) {
|
||||||
|
emitScrollToTop('Downloads');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
|
|
@ -1101,6 +1161,13 @@ const MainTabs = () => {
|
||||||
<MaterialCommunityIcons name={focused ? 'cog' : 'cog-outline'} size={size} color={color} />
|
<MaterialCommunityIcons name={focused ? 'cog' : 'cog-outline'} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
listeners={({ navigation }: any) => ({
|
||||||
|
tabPress: (e: any) => {
|
||||||
|
if (navigation.isFocused()) {
|
||||||
|
emitScrollToTop('Settings');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</Tab.Navigator>
|
</Tab.Navigator>
|
||||||
</View>
|
</View>
|
||||||
|
|
@ -1771,4 +1838,4 @@ const AppNavigator = ({ initialRouteName }: { initialRouteName?: keyof RootStack
|
||||||
</PostHogProvider>
|
</PostHogProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default AppNavigator;
|
export default AppNavigator;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue