mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-04-21 16:51:57 +00:00
updated tablet ui for plugin test screen
This commit is contained in:
parent
bb94a49662
commit
1fdcdd02bf
4 changed files with 163 additions and 134 deletions
|
|
@ -389,6 +389,14 @@ const SettingsScreen: React.FC = () => {
|
|||
renderControl={() => <ChevronRight />}
|
||||
isTablet={isTablet}
|
||||
/>
|
||||
<SettingItem
|
||||
title={'Plugin Tester'}
|
||||
description={'Run a plugin and inspect logs/streams'}
|
||||
icon="terminal"
|
||||
onPress={() => navigation.navigate('PluginTester')}
|
||||
renderControl={() => <ChevronRight />}
|
||||
isTablet={isTablet}
|
||||
/>
|
||||
<SettingItem
|
||||
title={t('settings.items.reset_onboarding')}
|
||||
icon="refresh-ccw"
|
||||
|
|
|
|||
|
|
@ -193,6 +193,7 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
<View style={styles.largeScreenWrapper}>
|
||||
<View style={styles.twoColumnContainer}>
|
||||
<View style={styles.leftColumn}>
|
||||
<View style={{ flex: 1 }}>
|
||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 10 }} keyboardShouldPersistTaps="handled">
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardTitleRow}>
|
||||
|
|
@ -246,11 +247,13 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
autoCorrect={false}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Test parameters on large screen */}
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardTitleRow}>
|
||||
<Text style={styles.cardTitle}>{t('plugin_tester.individual.test_parameters')}</Text>
|
||||
{/* Sticky footer on large screens (match mobile behavior) */}
|
||||
<View style={[styles.stickyFooter, { paddingBottom: Math.max(insets.bottom, 14) }]}>
|
||||
<View style={styles.footerCard}>
|
||||
<View style={styles.footerTitleRow}>
|
||||
<Text style={styles.footerTitle}>{t('plugin_tester.individual.test_parameters')}</Text>
|
||||
<Ionicons name="options-outline" size={16} color={currentTheme.colors.mediumEmphasis} />
|
||||
</View>
|
||||
|
||||
|
|
@ -305,9 +308,10 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[styles.button, { marginTop: 12, opacity: isRunning ? 0.85 : 1 }]}
|
||||
style={[styles.button, { opacity: isRunning ? 0.85 : 1 }]}
|
||||
onPress={runTest}
|
||||
disabled={isRunning}
|
||||
>
|
||||
|
|
@ -319,7 +323,7 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
<Text style={styles.buttonText}>{isRunning ? t('plugin_tester.common.running') : t('plugin_tester.common.run_test')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={styles.rightColumn}>
|
||||
|
|
@ -580,23 +584,33 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
} as any);
|
||||
};
|
||||
|
||||
const renderResultsTab = () => (
|
||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 40 }}>
|
||||
{streams.length === 0 ? (
|
||||
const renderResultsTab = () => {
|
||||
if (streams.length === 0) {
|
||||
return (
|
||||
<ScrollView style={styles.content}>
|
||||
<View style={styles.emptyState}>
|
||||
<Ionicons name="list-outline" size={48} color={currentTheme.colors.mediumGray} />
|
||||
<Text style={styles.emptyText}>{t('plugin_tester.individual.no_streams')}</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View style={styles.listContainer}>
|
||||
<Text style={styles.sectionHeader}>{streams.length === 1 ? t('plugin_tester.individual.streams_found', { count: streams.length }) : t('plugin_tester.individual.streams_found_plural', { count: streams.length })}</Text>
|
||||
<Text style={styles.sectionSubHeader}>{t('plugin_tester.individual.tap_play_hint')}</Text>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
style={styles.content}
|
||||
contentContainerStyle={{ paddingBottom: 40 }}
|
||||
data={streams}
|
||||
keyExtractor={(item, index) => item.url + index}
|
||||
ListHeaderComponent={
|
||||
<View style={{ paddingHorizontal: 16, paddingTop: 12, paddingBottom: 8 }}>
|
||||
<Text style={styles.sectionHeader}>{streams.length === 1 ? t('plugin_tester.individual.streams_found', { count: streams.length }) : t('plugin_tester.individual.streams_found_plural', { count: streams.length })}</Text>
|
||||
<Text style={styles.sectionSubHeader}>{t('plugin_tester.individual.tap_play_hint')}</Text>
|
||||
</View>
|
||||
}
|
||||
renderItem={({ item: stream }) => (
|
||||
<TouchableOpacity
|
||||
style={styles.resultItem}
|
||||
style={[styles.resultItem, { marginHorizontal: 16, marginBottom: 8 }]}
|
||||
onPress={() => playStream(stream)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
|
|
@ -641,10 +655,8 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
|||
</TouchableOpacity>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
const renderFocusedEditor = () => (
|
||||
<KeyboardAvoidingView
|
||||
|
|
|
|||
|
|
@ -363,6 +363,7 @@ export const RepoTester = () => {
|
|||
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
||||
keyboardVerticalOffset={Platform.OS === 'ios' ? 60 : 0}
|
||||
>
|
||||
<View style={isLargeScreen ? styles.largeScreenWrapper : { flex: 1 }}>
|
||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 20 }} keyboardShouldPersistTaps="handled">
|
||||
<View style={styles.card}>
|
||||
<View style={styles.cardTitleRow}>
|
||||
|
|
@ -624,6 +625,7 @@ export const RepoTester = () => {
|
|||
})}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { StyleSheet, Platform, useWindowDimensions } from 'react-native';
|
||||
|
||||
// Breakpoint for larger screens (tablets, iPads)
|
||||
export const LARGE_SCREEN_BREAKPOINT = 768;
|
||||
// Breakpoint for the two-column "large screen" layout.
|
||||
// 768px wide tablets in portrait are usually too narrow for side-by-side columns,
|
||||
// so we enable the large layout only on wider screens (e.g., tablet landscape).
|
||||
export const LARGE_SCREEN_BREAKPOINT = 900;
|
||||
|
||||
export const useIsLargeScreen = () => {
|
||||
const { width } = useWindowDimensions();
|
||||
|
|
@ -16,13 +18,16 @@ export const getPluginTesterStyles = (theme: any, isLargeScreen: boolean = false
|
|||
// Large screen wrapper for centering content
|
||||
largeScreenWrapper: {
|
||||
flex: 1,
|
||||
maxWidth: isLargeScreen ? 900 : undefined,
|
||||
// Allow tablet/desktop to use more horizontal space while still
|
||||
// keeping content comfortably contained.
|
||||
maxWidth: isLargeScreen ? 1200 : undefined,
|
||||
alignSelf: isLargeScreen ? 'center' : undefined,
|
||||
width: isLargeScreen ? '100%' : undefined,
|
||||
paddingHorizontal: isLargeScreen ? 24 : 0,
|
||||
},
|
||||
// Two-column layout for large screens
|
||||
twoColumnContainer: {
|
||||
flex: isLargeScreen ? 1 : undefined,
|
||||
flexDirection: isLargeScreen ? 'row' : 'column',
|
||||
gap: isLargeScreen ? 16 : 0,
|
||||
},
|
||||
|
|
@ -94,7 +99,9 @@ export const getPluginTesterStyles = (theme: any, isLargeScreen: boolean = false
|
|||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 16,
|
||||
// On large screens the wrapper already adds horizontal padding.
|
||||
// Avoid "double padding" that makes columns feel cramped.
|
||||
paddingHorizontal: isLargeScreen ? 0 : 16,
|
||||
paddingTop: 12,
|
||||
},
|
||||
card: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue