Enhance AddonsScreen UI and functionality; implement reorder mode for addons, improve header layout with back and refresh buttons, and refactor modal for addon installation details. Update styles for better visual consistency and user experience.

This commit is contained in:
Nayif Noushad 2025-04-22 19:05:16 +05:30
parent 9167767a65
commit c95d9d8093

View file

@ -63,7 +63,9 @@ const AddonsScreen = () => {
const [showConfirmModal, setShowConfirmModal] = useState(false); const [showConfirmModal, setShowConfirmModal] = useState(false);
const [installing, setInstalling] = useState(false); const [installing, setInstalling] = useState(false);
const [catalogCount, setCatalogCount] = useState(0); const [catalogCount, setCatalogCount] = useState(0);
// Add state for reorder mode
const [reorderMode, setReorderMode] = useState(false); const [reorderMode, setReorderMode] = useState(false);
// Force dark mode
const isDarkMode = true; const isDarkMode = true;
// State for community addons // State for community addons
@ -500,124 +502,333 @@ const AddonsScreen = () => {
); );
return ( return (
<SafeAreaView style={[styles.container, { backgroundColor: isDarkMode ? colors.background : colors.white }]}> <SafeAreaView style={styles.container}>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} /> <StatusBar barStyle="light-content" />
{/* Header */}
<View style={styles.header}> <View style={styles.header}>
<Text style={styles.title}>Addons</Text>
<TouchableOpacity onPress={toggleReorderMode} style={styles.reorderButton}>
<MaterialIcons
name={reorderMode ? "done" : "reorder"}
size={24}
color={colors.primary}
/>
</TouchableOpacity>
</View>
<View style={styles.statsContainer}>
<StatsCard value={addons.length} label="Installed" />
<StatsCard value={catalogCount} label="Catalogs" />
</View>
<View style={styles.searchContainer}>
<TextInput
style={styles.searchInput}
placeholder="Enter addon URL..."
placeholderTextColor={colors.mediumGray}
value={addonUrl}
onChangeText={setAddonUrl}
/>
<TouchableOpacity <TouchableOpacity
style={[styles.addButton, !addonUrl && styles.disabledButton]} style={styles.backButton}
onPress={() => handleAddAddon()} onPress={() => navigation.goBack()}
disabled={!addonUrl || installing}
> >
{installing ? ( <MaterialIcons name="chevron-left" size={28} color={colors.white} />
<ActivityIndicator size="small" color={colors.white} /> <Text style={styles.backText}>Settings</Text>
) : (
<MaterialIcons name="add" size={24} color={colors.white} />
)}
</TouchableOpacity> </TouchableOpacity>
<View style={styles.headerActions}>
{/* Reorder Mode Toggle Button */}
<TouchableOpacity
style={[styles.headerButton, reorderMode && styles.activeHeaderButton]}
onPress={toggleReorderMode}
>
<MaterialIcons
name="swap-vert"
size={24}
color={reorderMode ? colors.primary : colors.white}
/>
</TouchableOpacity>
{/* Refresh Button */}
<TouchableOpacity
style={styles.headerButton}
onPress={refreshAddons}
disabled={loading}
>
<MaterialIcons
name="refresh"
size={24}
color={loading ? colors.mediumGray : colors.white}
/>
</TouchableOpacity>
</View>
</View> </View>
<Text style={styles.headerTitle}>
Addons
{reorderMode && <Text style={styles.reorderModeText}> (Reorder Mode)</Text>}
</Text>
{reorderMode && (
<View style={styles.reorderInfoBanner}>
<MaterialIcons name="info-outline" size={18} color={colors.primary} />
<Text style={styles.reorderInfoText}>
Addons at the top have higher priority when loading content
</Text>
</View>
)}
{loading ? ( {loading ? (
<View style={styles.loadingContainer}> <View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.primary} /> <ActivityIndicator size="large" color={colors.primary} />
<Text style={styles.loadingText}>Loading addons...</Text>
</View> </View>
) : ( ) : (
<FlatList <ScrollView
data={addons} style={styles.scrollView}
renderItem={renderAddonItem} showsVerticalScrollIndicator={false}
keyExtractor={(item) => item.id} contentInsetAdjustmentBehavior="automatic"
style={styles.list} >
contentContainerStyle={styles.listContent} {/* Overview Section */}
ListEmptyComponent={() => ( <View style={styles.section}>
<View style={styles.emptyContainer}> <Text style={styles.sectionTitle}>OVERVIEW</Text>
<MaterialIcons name="extension-off" size={48} color={colors.mediumGray} /> <View style={styles.statsContainer}>
<Text style={styles.emptyText}>No addons installed</Text> <StatsCard value={addons.length} label="Addons" />
<Text style={styles.emptySubtext}>Add an addon using the URL field above</Text> <View style={styles.statsDivider} />
<StatsCard value={addons.length} label="Active" />
<View style={styles.statsDivider} />
<StatsCard value={catalogCount} label="Catalogs" />
</View>
</View>
{/* Hide Add Addon Section in reorder mode */}
{!reorderMode && (
<View style={styles.section}>
<Text style={styles.sectionTitle}>ADD NEW ADDON</Text>
<View style={styles.addAddonContainer}>
<TextInput
style={styles.addonInput}
placeholder="Addon URL"
placeholderTextColor={colors.mediumGray}
value={addonUrl}
onChangeText={setAddonUrl}
autoCapitalize="none"
autoCorrect={false}
/>
<TouchableOpacity
style={[styles.addButton, {opacity: installing || !addonUrl ? 0.6 : 1}]}
onPress={() => handleAddAddon()}
disabled={installing || !addonUrl}
>
<Text style={styles.addButtonText}>
{installing ? 'Loading...' : 'Add Addon'}
</Text>
</TouchableOpacity>
</View>
</View> </View>
)} )}
/>
{/* Installed Addons Section */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>
{reorderMode ? "DRAG ADDONS TO REORDER" : "INSTALLED ADDONS"}
</Text>
<View style={styles.addonList}>
{addons.length === 0 ? (
<View style={styles.emptyContainer}>
<MaterialIcons name="extension-off" size={32} color={colors.mediumGray} />
<Text style={styles.emptyText}>No addons installed</Text>
</View>
) : (
addons.map((addon, index) => (
<View
key={addon.id}
style={{ marginBottom: index === addons.length - 1 ? 32 : 0 }}
>
{renderAddonItem({ item: addon, index })}
</View>
))
)}
</View>
</View>
{/* Separator */}
<View style={styles.sectionSeparator} />
{/* Community Addons Section */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>COMMUNITY ADDONS</Text>
<View style={styles.addonList}>
{communityLoading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={colors.primary} />
</View>
) : communityError ? (
<View style={styles.emptyContainer}>
<MaterialIcons name="error-outline" size={32} color={colors.error} />
<Text style={styles.emptyText}>{communityError}</Text>
</View>
) : communityAddons.length === 0 ? (
<View style={styles.emptyContainer}>
<MaterialIcons name="extension-off" size={32} color={colors.mediumGray} />
<Text style={styles.emptyText}>No community addons available</Text>
</View>
) : (
communityAddons.map((item, index) => (
<View
key={item.transportUrl}
style={{ marginBottom: index === communityAddons.length - 1 ? 32 : 16 }}
>
<View style={styles.addonItem}>
<View style={styles.addonHeader}>
{item.manifest.logo ? (
<ExpoImage
source={{ uri: item.manifest.logo }}
style={styles.addonIcon}
contentFit="contain"
/>
) : (
<View style={styles.addonIconPlaceholder}>
<MaterialIcons name="extension" size={22} color={colors.mediumGray} />
</View>
)}
<View style={styles.addonTitleContainer}>
<Text style={styles.addonName}>{item.manifest.name}</Text>
<View style={styles.addonMetaContainer}>
<Text style={styles.addonVersion}>v{item.manifest.version || 'N/A'}</Text>
<Text style={styles.addonDot}></Text>
<Text style={styles.addonCategory}>
{item.manifest.types && item.manifest.types.length > 0
? item.manifest.types.map(t => t.charAt(0).toUpperCase() + t.slice(1)).join(' • ')
: 'General'}
</Text>
</View>
</View>
<View style={styles.addonActions}>
{item.manifest.behaviorHints?.configurable && (
<TouchableOpacity
style={styles.configButton}
onPress={() => handleConfigureAddon(item.manifest, item.transportUrl)}
>
<MaterialIcons name="settings" size={20} color={colors.primary} />
</TouchableOpacity>
)}
<TouchableOpacity
style={[styles.installButton, installing && { opacity: 0.6 }]}
onPress={() => handleAddAddon(item.transportUrl)}
disabled={installing}
>
{installing ? (
<ActivityIndicator size="small" color={colors.white} />
) : (
<MaterialIcons name="add" size={20} color={colors.white} />
)}
</TouchableOpacity>
</View>
</View>
<Text style={styles.addonDescription}>
{item.manifest.description
? (item.manifest.description.length > 100
? item.manifest.description.substring(0, 100) + '...'
: item.manifest.description)
: 'No description provided.'}
</Text>
</View>
</View>
))
)}
</View>
</View>
</ScrollView>
)} )}
{/* Community Addons Section */} {/* Addon Details Confirmation Modal */}
<View style={styles.communitySection}>
<Text style={styles.sectionTitle}>Community Addons</Text>
{communityLoading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="small" color={colors.primary} />
<Text style={styles.loadingText}>Loading community addons...</Text>
</View>
) : communityError ? (
<View style={styles.errorContainer}>
<MaterialIcons name="error-outline" size={24} color={colors.error} />
<Text style={styles.errorText}>{communityError}</Text>
</View>
) : (
<FlatList
data={communityAddons}
renderItem={renderCommunityAddonItem}
keyExtractor={(item) => item.manifest.id}
horizontal
showsHorizontalScrollIndicator={false}
style={styles.communityList}
contentContainerStyle={styles.communityListContent}
/>
)}
</View>
{/* Confirmation Modal */}
<Modal <Modal
visible={showConfirmModal} visible={showConfirmModal}
transparent transparent
animationType="fade" animationType="fade"
onRequestClose={() => setShowConfirmModal(false)} onRequestClose={() => {
setShowConfirmModal(false);
setAddonDetails(null);
}}
> >
<BlurView intensity={100} style={styles.modalOverlay}> <BlurView intensity={80} style={styles.modalContainer} tint="dark">
<View style={styles.modalContent}> <View style={styles.modalContent}>
<Text style={styles.modalTitle}>Install Addon</Text>
{addonDetails && ( {addonDetails && (
<> <>
<Text style={styles.modalAddonName}>{addonDetails.name}</Text> <View style={styles.modalHeader}>
<Text style={styles.modalAddonDesc}>{addonDetails.description}</Text> <Text style={styles.modalTitle}>Install Addon</Text>
<TouchableOpacity
onPress={() => {
setShowConfirmModal(false);
setAddonDetails(null);
}}
>
<MaterialIcons name="close" size={24} color={colors.white} />
</TouchableOpacity>
</View>
<ScrollView
style={styles.modalScrollContent}
showsVerticalScrollIndicator={false}
bounces={true}
>
<View style={styles.addonDetailHeader}>
{/* @ts-ignore */}
{addonDetails.logo ? (
<ExpoImage
source={{ uri: addonDetails.logo }}
style={styles.addonLogo}
contentFit="contain"
/>
) : (
<View style={styles.addonLogoPlaceholder}>
<MaterialIcons name="extension" size={40} color={colors.mediumGray} />
</View>
)}
<Text style={styles.addonDetailName}>{addonDetails.name}</Text>
<Text style={styles.addonDetailVersion}>v{addonDetails.version || '1.0.0'}</Text>
</View>
<View style={styles.addonDetailSection}>
<Text style={styles.addonDetailSectionTitle}>Description</Text>
<Text style={styles.addonDetailDescription}>
{addonDetails.description || 'No description available'}
</Text>
</View>
{addonDetails.types && addonDetails.types.length > 0 && (
<View style={styles.addonDetailSection}>
<Text style={styles.addonDetailSectionTitle}>Supported Types</Text>
<View style={styles.addonDetailChips}>
{addonDetails.types.map((type, index) => (
<View key={index} style={styles.addonDetailChip}>
<Text style={styles.addonDetailChipText}>{type}</Text>
</View>
))}
</View>
</View>
)}
{addonDetails.catalogs && addonDetails.catalogs.length > 0 && (
<View style={styles.addonDetailSection}>
<Text style={styles.addonDetailSectionTitle}>Catalogs</Text>
<View style={styles.addonDetailChips}>
{addonDetails.catalogs.map((catalog, index) => (
<View key={index} style={styles.addonDetailChip}>
<Text style={styles.addonDetailChipText}>
{catalog.type} - {catalog.id}
</Text>
</View>
))}
</View>
</View>
)}
</ScrollView>
<View style={styles.modalActions}>
<TouchableOpacity
style={[styles.modalButton, styles.cancelButton]}
onPress={() => {
setShowConfirmModal(false);
setAddonDetails(null);
}}
>
<Text style={styles.modalButtonText}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.modalButton, styles.installButton]}
onPress={confirmInstallAddon}
disabled={installing}
>
{installing ? (
<ActivityIndicator size="small" color={colors.white} />
) : (
<Text style={styles.modalButtonText}>Install</Text>
)}
</TouchableOpacity>
</View>
</> </>
)} )}
<View style={styles.modalButtons}>
<TouchableOpacity
style={[styles.modalButton, styles.cancelButton]}
onPress={() => setShowConfirmModal(false)}
>
<Text style={styles.modalButtonText}>Cancel</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.modalButton, styles.confirmButton]}
onPress={confirmInstallAddon}
>
<Text style={styles.modalButtonText}>Install</Text>
</TouchableOpacity>
</View>
</View> </View>
</BlurView> </BlurView>
</Modal> </Modal>
@ -628,156 +839,197 @@ const AddonsScreen = () => {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
flex: 1, flex: 1,
paddingTop: Platform.OS === 'android' ? ANDROID_STATUSBAR_HEIGHT : 0, backgroundColor: colors.darkBackground,
}, },
header: { header: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 16, paddingHorizontal: 16,
paddingVertical: 12, paddingTop: Platform.OS === 'android' ? ANDROID_STATUSBAR_HEIGHT + 8 : 8,
}, },
title: { headerActions: {
fontSize: 24,
fontWeight: 'bold',
color: colors.white,
},
statsContainer: {
flexDirection: 'row', flexDirection: 'row',
padding: 16,
justifyContent: 'space-around',
},
searchContainer: {
flexDirection: 'row',
paddingHorizontal: 16,
paddingBottom: 16,
alignItems: 'center', alignItems: 'center',
}, },
searchInput: { headerButton: {
flex: 1, padding: 8,
height: 40, marginLeft: 8,
backgroundColor: colors.darkGray,
borderRadius: 8,
paddingHorizontal: 12,
marginRight: 8,
color: colors.white,
}, },
addButton: { activeHeaderButton: {
width: 40, backgroundColor: 'rgba(45, 156, 219, 0.2)',
height: 40, borderRadius: 6,
backgroundColor: colors.primary, },
reorderModeText: {
color: colors.primary,
fontSize: 18,
fontWeight: '400',
},
reorderInfoBanner: {
backgroundColor: 'rgba(45, 156, 219, 0.15)',
paddingHorizontal: 16,
paddingVertical: 10,
marginHorizontal: 16,
borderRadius: 8, borderRadius: 8,
flexDirection: 'row',
alignItems: 'center',
marginBottom: 16,
},
reorderInfoText: {
color: colors.white,
fontSize: 14,
marginLeft: 8,
},
reorderButtons: {
position: 'absolute',
left: -12,
top: '50%',
marginTop: -40,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
zIndex: 10,
},
reorderButton: {
backgroundColor: colors.elevation3,
width: 30,
height: 30,
borderRadius: 15,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
marginVertical: 4,
}, },
disabledButton: { disabledButton: {
opacity: 0.5, opacity: 0.5,
backgroundColor: colors.elevation2,
}, },
list: { priorityBadge: {
flex: 1, backgroundColor: colors.primary,
},
listContent: {
paddingHorizontal: 16,
},
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
loadingText: {
marginTop: 12,
color: colors.mediumGray,
},
emptyContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 32,
},
emptyText: {
fontSize: 16,
color: colors.mediumGray,
marginTop: 16,
},
emptySubtext: {
fontSize: 14,
color: colors.mediumGray,
marginTop: 8,
},
modalOverlay: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.5)',
},
modalContent: {
backgroundColor: colors.darkGray,
borderRadius: 12, borderRadius: 12,
padding: 24, paddingHorizontal: 8,
width: '80%', paddingVertical: 3,
maxWidth: 400,
}, },
modalTitle: { priorityText: {
fontSize: 20, color: colors.white,
fontSize: 12,
fontWeight: 'bold', fontWeight: 'bold',
color: colors.white,
marginBottom: 16,
}, },
modalAddonName: { backButton: {
fontSize: 16, flexDirection: 'row',
color: colors.white, alignItems: 'center',
marginBottom: 8, padding: 8,
}, },
modalAddonDesc: { backText: {
fontSize: 14, fontSize: 17,
color: colors.mediumGray, fontWeight: '400',
color: colors.primary,
},
headerTitle: {
fontSize: 34,
fontWeight: '700',
color: colors.white,
paddingHorizontal: 16,
paddingBottom: 16,
paddingTop: 8,
},
scrollView: {
flex: 1,
},
section: {
marginBottom: 24, marginBottom: 24,
}, },
modalButtons: {
flexDirection: 'row',
justifyContent: 'flex-end',
},
modalButton: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 6,
marginLeft: 12,
},
modalButtonText: {
color: colors.white,
fontSize: 14,
fontWeight: '500',
},
cancelButton: {
backgroundColor: colors.mediumGray,
},
confirmButton: {
backgroundColor: colors.primary,
},
communitySection: {
paddingTop: 16,
},
sectionTitle: { sectionTitle: {
fontSize: 18, fontSize: 13,
fontWeight: '600',
color: colors.mediumGray,
marginHorizontal: 16,
marginBottom: 8,
letterSpacing: 0.5,
textTransform: 'uppercase',
},
statsContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginHorizontal: 16,
backgroundColor: colors.elevation2,
borderRadius: 12,
padding: 16,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
},
statsCard: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
statsDivider: {
width: 1,
height: '80%',
backgroundColor: 'rgba(150, 150, 150, 0.2)',
alignSelf: 'center',
},
statsValue: {
fontSize: 24,
fontWeight: 'bold', fontWeight: 'bold',
color: colors.white, color: colors.white,
paddingHorizontal: 16, marginBottom: 4,
marginBottom: 12,
}, },
communityList: { statsLabel: {
height: 160, fontSize: 13,
color: colors.mediumGray,
}, },
communityListContent: { addAddonContainer: {
paddingHorizontal: 16, marginHorizontal: 16,
}, backgroundColor: colors.elevation2,
errorContainer: { borderRadius: 12,
flexDirection: 'row',
alignItems: 'center',
padding: 16, padding: 16,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
}, },
errorText: { addonInput: {
color: colors.error, backgroundColor: colors.elevation1,
marginLeft: 8, borderRadius: 8,
padding: 12,
color: colors.white,
marginBottom: 16,
fontSize: 15,
},
addButton: {
backgroundColor: colors.primary,
borderRadius: 8,
padding: 12,
alignItems: 'center',
},
addButtonText: {
color: colors.white,
fontWeight: '600',
fontSize: 16,
},
addonList: {
paddingHorizontal: 16,
},
emptyContainer: {
backgroundColor: colors.elevation2,
borderRadius: 12,
padding: 32,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 2,
},
emptyText: {
marginTop: 8,
color: colors.mediumGray,
fontSize: 15,
}, },
addonItem: { addonItem: {
backgroundColor: colors.elevation2, backgroundColor: colors.elevation2,
@ -847,29 +1099,136 @@ const styles = StyleSheet.create({
lineHeight: 20, lineHeight: 20,
marginLeft: 48, // Align with title, accounting for icon width marginLeft: 48, // Align with title, accounting for icon width
}, },
reorderButton: { loadingContainer: {
padding: 8, flex: 1,
},
reorderButtons: {
position: 'absolute',
left: -12,
top: '50%',
marginTop: -40,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
zIndex: 10, alignItems: 'center',
}, },
priorityBadge: { modalContainer: {
backgroundColor: colors.primary, flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
modalContent: {
backgroundColor: colors.elevation2,
borderRadius: 14,
width: '85%',
maxHeight: '85%',
overflow: 'hidden',
shadowColor: '#000',
shadowOffset: { width: 0, height: 6 },
shadowOpacity: 0.25,
shadowRadius: 8,
elevation: 5,
},
modalHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 16,
borderBottomWidth: 1,
borderBottomColor: colors.elevation3,
},
modalTitle: {
fontSize: 17,
fontWeight: 'bold',
color: colors.white,
},
modalScrollContent: {
maxHeight: 400,
},
addonDetailHeader: {
alignItems: 'center',
padding: 24,
borderBottomWidth: 1,
borderBottomColor: colors.elevation3,
},
addonLogo: {
width: 64,
height: 64,
borderRadius: 12,
marginBottom: 16,
backgroundColor: colors.elevation3,
},
addonLogoPlaceholder: {
width: 64,
height: 64,
borderRadius: 12,
backgroundColor: colors.elevation3,
justifyContent: 'center',
alignItems: 'center',
marginBottom: 16,
},
addonDetailName: {
fontSize: 20,
fontWeight: 'bold',
color: colors.white,
marginBottom: 4,
textAlign: 'center',
},
addonDetailVersion: {
fontSize: 14,
color: colors.mediumGray,
},
addonDetailSection: {
padding: 16,
borderBottomWidth: 1,
borderBottomColor: colors.elevation3,
},
addonDetailSectionTitle: {
fontSize: 16,
fontWeight: '600',
color: colors.white,
marginBottom: 8,
},
addonDetailDescription: {
fontSize: 15,
color: colors.mediumEmphasis,
lineHeight: 20,
},
addonDetailChips: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 8,
},
addonDetailChip: {
backgroundColor: colors.elevation3,
borderRadius: 12, borderRadius: 12,
paddingHorizontal: 8, paddingHorizontal: 8,
paddingVertical: 3, paddingVertical: 4,
}, },
priorityText: { addonDetailChipText: {
fontSize: 13,
color: colors.white, color: colors.white,
fontSize: 12, },
fontWeight: 'bold', modalActions: {
flexDirection: 'row',
justifyContent: 'flex-end',
padding: 16,
borderTopWidth: 1,
borderTopColor: colors.elevation3,
},
modalButton: {
paddingVertical: 8,
paddingHorizontal: 16,
borderRadius: 8,
minWidth: 80,
alignItems: 'center',
},
cancelButton: {
backgroundColor: colors.elevation3,
marginRight: 8,
},
installButton: {
backgroundColor: colors.success,
borderRadius: 6,
padding: 8,
justifyContent: 'center',
alignItems: 'center',
},
modalButtonText: {
color: colors.white,
fontWeight: '600',
}, },
addonActions: { addonActions: {
flexDirection: 'row', flexDirection: 'row',
@ -882,6 +1241,9 @@ const styles = StyleSheet.create({
padding: 6, padding: 6,
marginRight: 8, marginRight: 8,
}, },
communityAddonsList: {
paddingHorizontal: 20,
},
communityAddonItem: { communityAddonItem: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
@ -971,30 +1333,6 @@ const styles = StyleSheet.create({
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
}, },
installButton: {
backgroundColor: colors.success,
borderRadius: 6,
padding: 8,
justifyContent: 'center',
alignItems: 'center',
},
statsCard: {
backgroundColor: colors.darkGray,
borderRadius: 8,
padding: 12,
alignItems: 'center',
minWidth: 100,
},
statsValue: {
fontSize: 24,
fontWeight: 'bold',
color: colors.white,
marginBottom: 4,
},
statsLabel: {
fontSize: 13,
color: colors.mediumGray,
},
}); });
export default AddonsScreen; export default AddonsScreen;