mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-01-11 20:10:25 +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 />}
|
renderControl={() => <ChevronRight />}
|
||||||
isTablet={isTablet}
|
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
|
<SettingItem
|
||||||
title={t('settings.items.reset_onboarding')}
|
title={t('settings.items.reset_onboarding')}
|
||||||
icon="refresh-ccw"
|
icon="refresh-ccw"
|
||||||
|
|
|
||||||
|
|
@ -193,8 +193,9 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
||||||
<View style={styles.largeScreenWrapper}>
|
<View style={styles.largeScreenWrapper}>
|
||||||
<View style={styles.twoColumnContainer}>
|
<View style={styles.twoColumnContainer}>
|
||||||
<View style={styles.leftColumn}>
|
<View style={styles.leftColumn}>
|
||||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 10 }} keyboardShouldPersistTaps="handled">
|
<View style={{ flex: 1 }}>
|
||||||
<View style={styles.card}>
|
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 10 }} keyboardShouldPersistTaps="handled">
|
||||||
|
<View style={styles.card}>
|
||||||
<View style={styles.cardTitleRow}>
|
<View style={styles.cardTitleRow}>
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.individual.load_from_url')}</Text>
|
<Text style={styles.cardTitle}>{t('plugin_tester.individual.load_from_url')}</Text>
|
||||||
<Ionicons name="link-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
<Ionicons name="link-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
||||||
|
|
@ -219,9 +220,9 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
||||||
<Ionicons name="download-outline" size={20} color={currentTheme.colors.white} />
|
<Ionicons name="download-outline" size={20} color={currentTheme.colors.white} />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[styles.card, { flex: 1, minHeight: 400 }]}>
|
<View style={[styles.card, { flex: 1, minHeight: 400 }]}>
|
||||||
<View style={styles.cardTitleRow}>
|
<View style={styles.cardTitleRow}>
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.individual.plugin_code')}</Text>
|
<Text style={styles.cardTitle}>{t('plugin_tester.individual.plugin_code')}</Text>
|
||||||
<View style={styles.cardActionsRow}>
|
<View style={styles.cardActionsRow}>
|
||||||
|
|
@ -245,69 +246,72 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
||||||
autoCapitalize="none"
|
autoCapitalize="none"
|
||||||
autoCorrect={false}
|
autoCorrect={false}
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* Test parameters on large screen */}
|
|
||||||
<View style={styles.card}>
|
|
||||||
<View style={styles.cardTitleRow}>
|
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.individual.test_parameters')}</Text>
|
|
||||||
<Ionicons name="options-outline" size={16} color={currentTheme.colors.mediumEmphasis} />
|
|
||||||
</View>
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
<View style={styles.segment}>
|
{/* Sticky footer on large screens (match mobile behavior) */}
|
||||||
<TouchableOpacity
|
<View style={[styles.stickyFooter, { paddingBottom: Math.max(insets.bottom, 14) }]}>
|
||||||
style={[styles.segmentItem, mediaType === 'movie' && styles.segmentItemActive]}
|
<View style={styles.footerCard}>
|
||||||
onPress={() => setMediaType('movie')}
|
<View style={styles.footerTitleRow}>
|
||||||
>
|
<Text style={styles.footerTitle}>{t('plugin_tester.individual.test_parameters')}</Text>
|
||||||
<Ionicons name="film-outline" size={18} color={mediaType === 'movie' ? currentTheme.colors.primary : currentTheme.colors.highEmphasis} />
|
<Ionicons name="options-outline" size={16} color={currentTheme.colors.mediumEmphasis} />
|
||||||
<Text style={[styles.segmentText, mediaType === 'movie' && styles.segmentTextActive]}>{t('plugin_tester.common.movie')}</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
style={[styles.segmentItem, mediaType === 'tv' && styles.segmentItemActive]}
|
|
||||||
onPress={() => setMediaType('tv')}
|
|
||||||
>
|
|
||||||
<Ionicons name="tv-outline" size={18} color={mediaType === 'tv' ? currentTheme.colors.primary : currentTheme.colors.highEmphasis} />
|
|
||||||
<Text style={[styles.segmentText, mediaType === 'tv' && styles.segmentTextActive]}>{t('plugin_tester.common.tv')}</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<View style={[styles.row, { marginTop: 10, alignItems: 'flex-start' }]}>
|
|
||||||
<View style={{ flex: 1 }}>
|
|
||||||
<Text style={styles.fieldLabel}>{t('plugin_tester.common.tmdb_id')}</Text>
|
|
||||||
<TextInput
|
|
||||||
style={styles.input}
|
|
||||||
value={tmdbId}
|
|
||||||
onChangeText={setTmdbId}
|
|
||||||
keyboardType="numeric"
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
{mediaType === 'tv' && (
|
<View style={styles.segment}>
|
||||||
<>
|
<TouchableOpacity
|
||||||
<View style={{ width: 110 }}>
|
style={[styles.segmentItem, mediaType === 'movie' && styles.segmentItemActive]}
|
||||||
<Text style={styles.fieldLabel}>{t('plugin_tester.common.season')}</Text>
|
onPress={() => setMediaType('movie')}
|
||||||
<TextInput
|
>
|
||||||
style={styles.input}
|
<Ionicons name="film-outline" size={18} color={mediaType === 'movie' ? currentTheme.colors.primary : currentTheme.colors.highEmphasis} />
|
||||||
value={season}
|
<Text style={[styles.segmentText, mediaType === 'movie' && styles.segmentTextActive]}>{t('plugin_tester.common.movie')}</Text>
|
||||||
onChangeText={setSeason}
|
</TouchableOpacity>
|
||||||
keyboardType="numeric"
|
<TouchableOpacity
|
||||||
/>
|
style={[styles.segmentItem, mediaType === 'tv' && styles.segmentItemActive]}
|
||||||
</View>
|
onPress={() => setMediaType('tv')}
|
||||||
<View style={{ width: 110 }}>
|
>
|
||||||
<Text style={styles.fieldLabel}>{t('plugin_tester.common.episode')}</Text>
|
<Ionicons name="tv-outline" size={18} color={mediaType === 'tv' ? currentTheme.colors.primary : currentTheme.colors.highEmphasis} />
|
||||||
<TextInput
|
<Text style={[styles.segmentText, mediaType === 'tv' && styles.segmentTextActive]}>{t('plugin_tester.common.tv')}</Text>
|
||||||
style={styles.input}
|
</TouchableOpacity>
|
||||||
value={episode}
|
</View>
|
||||||
onChangeText={setEpisode}
|
|
||||||
keyboardType="numeric"
|
<View style={[styles.row, { marginTop: 10, alignItems: 'flex-start' }]}>
|
||||||
/>
|
<View style={{ flex: 1 }}>
|
||||||
</View>
|
<Text style={styles.fieldLabel}>{t('plugin_tester.common.tmdb_id')}</Text>
|
||||||
</>
|
<TextInput
|
||||||
)}
|
style={styles.input}
|
||||||
|
value={tmdbId}
|
||||||
|
onChangeText={setTmdbId}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{mediaType === 'tv' && (
|
||||||
|
<>
|
||||||
|
<View style={{ width: 110 }}>
|
||||||
|
<Text style={styles.fieldLabel}>{t('plugin_tester.common.season')}</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={season}
|
||||||
|
onChangeText={setSeason}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={{ width: 110 }}>
|
||||||
|
<Text style={styles.fieldLabel}>{t('plugin_tester.common.episode')}</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.input}
|
||||||
|
value={episode}
|
||||||
|
onChangeText={setEpisode}
|
||||||
|
keyboardType="numeric"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={[styles.button, { marginTop: 12, opacity: isRunning ? 0.85 : 1 }]}
|
style={[styles.button, { opacity: isRunning ? 0.85 : 1 }]}
|
||||||
onPress={runTest}
|
onPress={runTest}
|
||||||
disabled={isRunning}
|
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>
|
<Text style={styles.buttonText}>{isRunning ? t('plugin_tester.common.running') : t('plugin_tester.common.run_test')}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.rightColumn}>
|
<View style={styles.rightColumn}>
|
||||||
|
|
@ -580,71 +584,79 @@ export const IndividualTester = ({ onSwitchTab }: IndividualTesterProps) => {
|
||||||
} as any);
|
} as any);
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderResultsTab = () => (
|
const renderResultsTab = () => {
|
||||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 40 }}>
|
if (streams.length === 0) {
|
||||||
{streams.length === 0 ? (
|
return (
|
||||||
<View style={styles.emptyState}>
|
<ScrollView style={styles.content}>
|
||||||
<Ionicons name="list-outline" size={48} color={currentTheme.colors.mediumGray} />
|
<View style={styles.emptyState}>
|
||||||
<Text style={styles.emptyText}>{t('plugin_tester.individual.no_streams')}</Text>
|
<Ionicons name="list-outline" size={48} color={currentTheme.colors.mediumGray} />
|
||||||
</View>
|
<Text style={styles.emptyText}>{t('plugin_tester.individual.no_streams')}</Text>
|
||||||
) : (
|
</View>
|
||||||
<View style={styles.listContainer}>
|
</ScrollView>
|
||||||
<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>
|
}
|
||||||
<FlatList
|
|
||||||
data={streams}
|
|
||||||
keyExtractor={(item, index) => item.url + index}
|
|
||||||
renderItem={({ item: stream }) => (
|
|
||||||
<TouchableOpacity
|
|
||||||
style={styles.resultItem}
|
|
||||||
onPress={() => playStream(stream)}
|
|
||||||
activeOpacity={0.7}
|
|
||||||
>
|
|
||||||
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' }}>
|
|
||||||
<View style={styles.streamInfo}>
|
|
||||||
<Text style={styles.streamName}>{stream.name || stream.title || t('plugin_tester.individual.unnamed_stream')}</Text>
|
|
||||||
<Text style={styles.streamMeta}>{t('plugin_tester.individual.quality', { quality: stream.quality || 'Unknown' })}</Text>
|
|
||||||
{stream.description ? <Text style={styles.streamMeta}>{t('plugin_tester.individual.size', { size: stream.description })}</Text> : null}
|
|
||||||
<Text style={styles.streamMeta} numberOfLines={1}>{t('plugin_tester.individual.url_label', { url: stream.url })}</Text>
|
|
||||||
{stream.headers && Object.keys(stream.headers).length > 0 && (
|
|
||||||
<Text style={styles.streamMeta}>{t('plugin_tester.individual.headers_info', { count: Object.keys(stream.headers).length })}</Text>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<TouchableOpacity
|
|
||||||
style={styles.playButton}
|
|
||||||
onPress={() => playStream(stream)}
|
|
||||||
>
|
|
||||||
<Ionicons name="play" size={16} color={currentTheme.colors.white} />
|
|
||||||
<Text style={styles.playButtonText}>{t('plugin_tester.common.play')}</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Text
|
return (
|
||||||
style={[
|
<FlatList
|
||||||
styles.logItem,
|
style={styles.content}
|
||||||
{
|
contentContainerStyle={{ paddingBottom: 40 }}
|
||||||
marginTop: 10,
|
data={streams}
|
||||||
marginBottom: 0,
|
keyExtractor={(item, index) => item.url + index}
|
||||||
color: currentTheme.colors.highEmphasis,
|
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>
|
||||||
selectable
|
<Text style={styles.sectionSubHeader}>{t('plugin_tester.individual.tap_play_hint')}</Text>
|
||||||
>
|
</View>
|
||||||
{(() => {
|
}
|
||||||
try {
|
renderItem={({ item: stream }) => (
|
||||||
return JSON.stringify(stream, null, 2);
|
<TouchableOpacity
|
||||||
} catch {
|
style={[styles.resultItem, { marginHorizontal: 16, marginBottom: 8 }]}
|
||||||
return String(stream);
|
onPress={() => playStream(stream)}
|
||||||
}
|
activeOpacity={0.7}
|
||||||
})()}
|
>
|
||||||
</Text>
|
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start' }}>
|
||||||
|
<View style={styles.streamInfo}>
|
||||||
|
<Text style={styles.streamName}>{stream.name || stream.title || t('plugin_tester.individual.unnamed_stream')}</Text>
|
||||||
|
<Text style={styles.streamMeta}>{t('plugin_tester.individual.quality', { quality: stream.quality || 'Unknown' })}</Text>
|
||||||
|
{stream.description ? <Text style={styles.streamMeta}>{t('plugin_tester.individual.size', { size: stream.description })}</Text> : null}
|
||||||
|
<Text style={styles.streamMeta} numberOfLines={1}>{t('plugin_tester.individual.url_label', { url: stream.url })}</Text>
|
||||||
|
{stream.headers && Object.keys(stream.headers).length > 0 && (
|
||||||
|
<Text style={styles.streamMeta}>{t('plugin_tester.individual.headers_info', { count: Object.keys(stream.headers).length })}</Text>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.playButton}
|
||||||
|
onPress={() => playStream(stream)}
|
||||||
|
>
|
||||||
|
<Ionicons name="play" size={16} color={currentTheme.colors.white} />
|
||||||
|
<Text style={styles.playButtonText}>{t('plugin_tester.common.play')}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
</View>
|
||||||
/>
|
|
||||||
</View>
|
<Text
|
||||||
)}
|
style={[
|
||||||
</ScrollView>
|
styles.logItem,
|
||||||
);
|
{
|
||||||
|
marginTop: 10,
|
||||||
|
marginBottom: 0,
|
||||||
|
color: currentTheme.colors.highEmphasis,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
selectable
|
||||||
|
>
|
||||||
|
{(() => {
|
||||||
|
try {
|
||||||
|
return JSON.stringify(stream, null, 2);
|
||||||
|
} catch {
|
||||||
|
return String(stream);
|
||||||
|
}
|
||||||
|
})()}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const renderFocusedEditor = () => (
|
const renderFocusedEditor = () => (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
|
|
|
||||||
|
|
@ -363,8 +363,9 @@ export const RepoTester = () => {
|
||||||
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
|
||||||
keyboardVerticalOffset={Platform.OS === 'ios' ? 60 : 0}
|
keyboardVerticalOffset={Platform.OS === 'ios' ? 60 : 0}
|
||||||
>
|
>
|
||||||
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 20 }} keyboardShouldPersistTaps="handled">
|
<View style={isLargeScreen ? styles.largeScreenWrapper : { flex: 1 }}>
|
||||||
<View style={styles.card}>
|
<ScrollView style={styles.content} contentContainerStyle={{ paddingBottom: 20 }} keyboardShouldPersistTaps="handled">
|
||||||
|
<View style={styles.card}>
|
||||||
<View style={styles.cardTitleRow}>
|
<View style={styles.cardTitleRow}>
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.repo.title')}</Text>
|
<Text style={styles.cardTitle}>{t('plugin_tester.repo.title')}</Text>
|
||||||
<Ionicons name="git-branch-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
<Ionicons name="git-branch-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
||||||
|
|
@ -409,7 +410,7 @@ export const RepoTester = () => {
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.card}>
|
<View style={styles.card}>
|
||||||
<View style={styles.cardTitleRow}>
|
<View style={styles.cardTitleRow}>
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.repo.test_parameters')}</Text>
|
<Text style={styles.cardTitle}>{t('plugin_tester.repo.test_parameters')}</Text>
|
||||||
<Ionicons name="options-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
<Ionicons name="options-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
||||||
|
|
@ -475,7 +476,7 @@ export const RepoTester = () => {
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={styles.card}>
|
<View style={styles.card}>
|
||||||
<View style={styles.cardTitleRow}>
|
<View style={styles.cardTitleRow}>
|
||||||
<Text style={styles.cardTitle}>{t('plugin_tester.repo.providers_title')}</Text>
|
<Text style={styles.cardTitle}>{t('plugin_tester.repo.providers_title')}</Text>
|
||||||
<Ionicons name="list-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
<Ionicons name="list-outline" size={18} color={currentTheme.colors.mediumEmphasis} />
|
||||||
|
|
@ -622,8 +623,9 @@ export const RepoTester = () => {
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
</View>
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import { StyleSheet, Platform, useWindowDimensions } from 'react-native';
|
import { StyleSheet, Platform, useWindowDimensions } from 'react-native';
|
||||||
|
|
||||||
// Breakpoint for larger screens (tablets, iPads)
|
// Breakpoint for the two-column "large screen" layout.
|
||||||
export const LARGE_SCREEN_BREAKPOINT = 768;
|
// 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 = () => {
|
export const useIsLargeScreen = () => {
|
||||||
const { width } = useWindowDimensions();
|
const { width } = useWindowDimensions();
|
||||||
|
|
@ -16,13 +18,16 @@ export const getPluginTesterStyles = (theme: any, isLargeScreen: boolean = false
|
||||||
// Large screen wrapper for centering content
|
// Large screen wrapper for centering content
|
||||||
largeScreenWrapper: {
|
largeScreenWrapper: {
|
||||||
flex: 1,
|
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,
|
alignSelf: isLargeScreen ? 'center' : undefined,
|
||||||
width: isLargeScreen ? '100%' : undefined,
|
width: isLargeScreen ? '100%' : undefined,
|
||||||
paddingHorizontal: isLargeScreen ? 24 : 0,
|
paddingHorizontal: isLargeScreen ? 24 : 0,
|
||||||
},
|
},
|
||||||
// Two-column layout for large screens
|
// Two-column layout for large screens
|
||||||
twoColumnContainer: {
|
twoColumnContainer: {
|
||||||
|
flex: isLargeScreen ? 1 : undefined,
|
||||||
flexDirection: isLargeScreen ? 'row' : 'column',
|
flexDirection: isLargeScreen ? 'row' : 'column',
|
||||||
gap: isLargeScreen ? 16 : 0,
|
gap: isLargeScreen ? 16 : 0,
|
||||||
},
|
},
|
||||||
|
|
@ -94,7 +99,9 @@ export const getPluginTesterStyles = (theme: any, isLargeScreen: boolean = false
|
||||||
},
|
},
|
||||||
content: {
|
content: {
|
||||||
flex: 1,
|
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,
|
paddingTop: 12,
|
||||||
},
|
},
|
||||||
card: {
|
card: {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue