Pluginscreen UI changes

This commit is contained in:
tapframe 2025-09-30 01:39:00 +05:30
parent 9ae0a7010c
commit bbbc22f30f
5 changed files with 87 additions and 35 deletions

View file

@ -57,6 +57,8 @@ export interface AppSettings {
excludedQualities: string[]; // Array of quality strings to exclude (e.g., ['2160p', '4K', '1080p', '720p'])
// Playback behavior
alwaysResume: boolean; // If true, resume automatically without prompt when progress < 85%
// Downloads
enableDownloads: boolean; // Show Downloads tab and enable saving streams
// Theme settings
themeId: string;
customThemes: CustomThemeDef[];
@ -105,6 +107,8 @@ export const DEFAULT_SETTINGS: AppSettings = {
excludedQualities: [], // No qualities excluded by default
// Playback behavior defaults
alwaysResume: true,
// Downloads
enableDownloads: false,
// Theme defaults
themeId: 'default',
customThemes: [],

View file

@ -458,6 +458,9 @@ const WrappedScreen: React.FC<{Screen: React.ComponentType<any>}> = ({ Screen })
// Tab Navigator
const MainTabs = () => {
const { currentTheme } = useTheme();
const { settings } = require('../hooks/useSettings');
const { useSettings: useSettingsHook } = require('../hooks/useSettings');
const { settings: appSettings } = useSettingsHook();
const [hasUpdateBadge, setHasUpdateBadge] = React.useState(false);
React.useEffect(() => {
if (Platform.OS !== 'android') return;
@ -829,16 +832,18 @@ const MainTabs = () => {
),
}}
/>
<Tab.Screen
name="Downloads"
component={DownloadsScreen}
options={{
tabBarLabel: 'Downloads',
tabBarIcon: ({ color, size, focused }) => (
<MaterialCommunityIcons name={focused ? 'download' : 'download-outline'} size={size} color={color} />
),
}}
/>
{appSettings?.enableDownloads !== false && (
<Tab.Screen
name="Downloads"
component={DownloadsScreen}
options={{
tabBarLabel: 'Downloads',
tabBarIcon: ({ color, size, focused }) => (
<MaterialCommunityIcons name={focused ? 'download' : 'download-outline'} size={size} color={color} />
),
}}
/>
)}
<Tab.Screen
name="Settings"
component={SettingsScreen}

View file

@ -33,7 +33,7 @@ const ANDROID_STATUSBAR_HEIGHT = StatusBar.currentHeight || 0;
const createStyles = (colors: any) => StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background,
backgroundColor: colors.darkBackground,
},
header: {
flexDirection: 'row',
@ -63,7 +63,7 @@ const createStyles = (colors: any) => StyleSheet.create({
headerTitle: {
fontSize: 34,
fontWeight: 'bold',
color: colors.white,
color: colors.text,
paddingHorizontal: 16,
marginBottom: 24,
},
@ -71,7 +71,7 @@ const createStyles = (colors: any) => StyleSheet.create({
flex: 1,
},
section: {
backgroundColor: colors.darkBackground,
backgroundColor: colors.elevation1,
marginBottom: 16,
borderRadius: 12,
padding: 16,
@ -852,6 +852,7 @@ const PluginsScreen: React.FC = () => {
const [showboxUiToken, setShowboxUiToken] = useState<string>('');
const [showboxSavedToken, setShowboxSavedToken] = useState<string>('');
const [showboxScraperId, setShowboxScraperId] = useState<string | null>(null);
const [showboxTokenVisible, setShowboxTokenVisible] = useState<boolean>(false);
// Multiple repositories state
const [repositories, setRepositories] = useState<RepositoryInfo[]>([]);
@ -1084,10 +1085,12 @@ const PluginsScreen: React.FC = () => {
const s = await localScraperService.getScraperSettings(sb.id);
setShowboxUiToken(s.uiToken || '');
setShowboxSavedToken(s.uiToken || '');
setShowboxTokenVisible(false);
} else {
setShowboxScraperId(null);
setShowboxUiToken('');
setShowboxSavedToken('');
setShowboxTokenVisible(false);
}
} catch (error) {
logger.error('[ScraperSettings] Failed to load scrapers:', error);
@ -1630,17 +1633,25 @@ const PluginsScreen: React.FC = () => {
{showboxScraperId && scraper.id === showboxScraperId && settings.enableLocalScrapers && (
<View style={{ marginTop: 16, paddingTop: 16, borderTopWidth: 1, borderTopColor: colors.elevation3 }}>
<Text style={[styles.settingTitle, { marginBottom: 8 }]}>ShowBox UI Token</Text>
<TextInput
style={[styles.textInput, { marginBottom: 12 }]}
value={showboxUiToken}
onChangeText={setShowboxUiToken}
placeholder="Paste your ShowBox UI token"
placeholderTextColor={colors.mediumGray}
autoCapitalize="none"
autoCorrect={false}
multiline={true}
numberOfLines={3}
/>
<View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 12 }}>
<TextInput
style={[styles.textInput, { flex: 1, marginBottom: 0 }]}
value={showboxUiToken}
onChangeText={setShowboxUiToken}
placeholder="Paste your ShowBox UI token"
placeholderTextColor={colors.mediumGray}
autoCapitalize="none"
autoCorrect={false}
secureTextEntry={showboxSavedToken.length > 0 && !showboxTokenVisible}
multiline={false}
numberOfLines={1}
/>
{showboxSavedToken.length > 0 && (
<TouchableOpacity onPress={() => setShowboxTokenVisible(v => !v)} accessibilityRole="button" accessibilityLabel={showboxTokenVisible ? 'Hide token' : 'Show token'} style={{ marginLeft: 10 }}>
<Ionicons name={showboxTokenVisible ? 'eye-off' : 'eye'} size={18} color={colors.primary} />
</TouchableOpacity>
)}
</View>
<View style={styles.buttonRow}>
{showboxUiToken !== showboxSavedToken && (
<TouchableOpacity

View file

@ -278,6 +278,8 @@ const SettingsScreen: React.FC = () => {
// Tablet-specific state
const [selectedCategory, setSelectedCategory] = useState('account');
const [downloadsDevUnlocked, setDownloadsDevUnlocked] = useState(false);
const [versionTapCount, setVersionTapCount] = useState(0);
// States for dynamic content
const [addonCount, setAddonCount] = useState<number>(0);
@ -613,6 +615,22 @@ const SettingsScreen: React.FC = () => {
)}
isTablet={isTablet}
/>
{downloadsDevUnlocked && (
<SettingItem
title="Enable Downloads"
description="Show Downloads tab and enable saving streams"
icon="download"
renderControl={() => (
<Switch
value={settings?.enableDownloads ?? true}
onValueChange={(value) => updateSetting('enableDownloads', value)}
trackColor={{ false: 'rgba(255,255,255,0.2)', true: currentTheme.colors.primary }}
thumbColor={settings?.enableDownloads ? '#fff' : '#f4f3f4'}
/>
)}
isTablet={isTablet}
/>
)}
<SettingItem
title="Notifications"
description="Episode reminders"
@ -646,6 +664,16 @@ const SettingsScreen: React.FC = () => {
title="Version"
description={getDisplayedAppVersion()}
icon="info-outline"
onPress={() => {
if (downloadsDevUnlocked) return;
const next = versionTapCount + 1;
setVersionTapCount(next);
if (next >= 5) {
setDownloadsDevUnlocked(true);
setVersionTapCount(0);
openAlert('Developer option unlocked', 'Downloads toggle is now visible in Playback settings.');
}
}}
isLast={true}
isTablet={isTablet}
/>

View file

@ -221,6 +221,8 @@ const StreamCard = memo(({ stream, onPress, index, isLoading, statusMessage, the
parentPosterUrl?: string | null;
providerName?: string;
}) => {
const { useSettings } = require('../hooks/useSettings');
const { settings } = useSettings();
const { startDownload } = useDownloads();
// Handle long press to copy stream URL to clipboard
@ -398,17 +400,19 @@ const StreamCard = memo(({ stream, onPress, index, isLoading, statusMessage, the
color={theme.colors.white}
/>
</View>
<TouchableOpacity
style={[styles.streamAction, { marginLeft: 8, backgroundColor: theme.colors.elevation2 }]}
onPress={handleDownload}
activeOpacity={0.7}
>
<MaterialIcons
name="download"
size={20}
color={theme.colors.highEmphasis}
/>
</TouchableOpacity>
{settings?.enableDownloads !== false && (
<TouchableOpacity
style={[styles.streamAction, { marginLeft: 8, backgroundColor: theme.colors.elevation2 }]}
onPress={handleDownload}
activeOpacity={0.7}
>
<MaterialIcons
name="download"
size={20}
color={theme.colors.highEmphasis}
/>
</TouchableOpacity>
)}
</TouchableOpacity>
);
});