update
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
View, Text, ScrollView, TouchableOpacity, TextInput, StyleSheet, Alert,
|
||||
View, Text, ScrollView, TouchableOpacity, TextInput, StyleSheet, Alert, Modal, KeyboardAvoidingView, Platform,
|
||||
} from 'react-native';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
@@ -49,7 +49,8 @@ export default function NewFilamentScreen(): React.ReactElement {
|
||||
const [selectedMaterial, setSelectedMaterial] = useState<Material>('PLA');
|
||||
const [selectedPresetId, setSelectedPresetId] = useState<string | null>(systemPresets[0]?.id ?? null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isOpeningColorPicker, setIsOpeningColorPicker] = useState(false);
|
||||
const [isColorPickerOpen, setIsColorPickerOpen] = useState(false);
|
||||
const [colorInputValue, setColorInputValue] = useState('');
|
||||
|
||||
// Quando os presets carregam (via layout), seleciona o primeiro sistema automaticamente
|
||||
useEffect(() => {
|
||||
@@ -69,33 +70,32 @@ export default function NewFilamentScreen(): React.ReactElement {
|
||||
? calcNetWeight(Number(totalWeight), selectedPreset.spoolWeightG)
|
||||
: 0;
|
||||
const pct = Math.min(100, Math.round((netWeight / 1000) * 100));
|
||||
function handleOpenColorPicker(): void {
|
||||
if (isOpeningColorPicker) return;
|
||||
setIsOpeningColorPicker(true);
|
||||
Alert.prompt(
|
||||
'Cor Customizada',
|
||||
'Digite um código de cor hexadecimal (ex: #FF5733)',
|
||||
[
|
||||
{ text: 'Cancelar', style: 'cancel', onPress: () => setIsOpeningColorPicker(false) },
|
||||
{
|
||||
text: 'Confirmar',
|
||||
onPress: (value) => {
|
||||
setIsOpeningColorPicker(false);
|
||||
if (!value) return;
|
||||
const normalized = normalizeHex(value.trim());
|
||||
if (isValidHex(normalized)) {
|
||||
setSelectedColor(normalized);
|
||||
setHexInput(normalized);
|
||||
} else {
|
||||
Alert.alert('Erro', 'Código hexadecimal inválido. Use o formato #RRGGBB ou #RGB.');
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
'plain-text',
|
||||
selectedColor,
|
||||
);
|
||||
}
|
||||
|
||||
const handleOpenColorPicker = (): void => {
|
||||
setColorInputValue(selectedColor);
|
||||
setIsColorPickerOpen(true);
|
||||
};
|
||||
|
||||
const handleConfirmColor = (): void => {
|
||||
if (!colorInputValue) {
|
||||
Alert.alert('Erro', 'Digite um código hexadecimal');
|
||||
return;
|
||||
}
|
||||
const normalized = normalizeHex(colorInputValue.trim());
|
||||
if (isValidHex(normalized)) {
|
||||
setSelectedColor(normalized);
|
||||
setHexInput(normalized);
|
||||
setIsColorPickerOpen(false);
|
||||
setColorInputValue('');
|
||||
} else {
|
||||
Alert.alert('Erro', 'Código hexadecimal inválido. Use o formato #RRGGBB ou #RGB.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancelColor = (): void => {
|
||||
setIsColorPickerOpen(false);
|
||||
setColorInputValue('');
|
||||
};
|
||||
|
||||
|
||||
async function onSubmit(data: FormData): Promise<void> {
|
||||
@@ -132,7 +132,34 @@ function handleOpenColorPicker(): void {
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.safe}> onPress={handleOpenColorPicker}
|
||||
<>
|
||||
<Modal visible={isColorPickerOpen} transparent animationType="fade">
|
||||
<View style={styles.modalOverlay}>
|
||||
<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'} style={styles.modalContent}>
|
||||
<View style={styles.modalCard}>
|
||||
<Text style={styles.modalTitle}>Código Hexadecimal</Text>
|
||||
<TextInput
|
||||
style={styles.modalInput}
|
||||
placeholder="#FF5733"
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
value={colorInputValue}
|
||||
onChangeText={setColorInputValue}
|
||||
autoFocus
|
||||
/>
|
||||
<View style={styles.modalButtons}>
|
||||
<TouchableOpacity onPress={handleCancelColor} style={styles.modalBtnCancel}>
|
||||
<Text style={styles.modalBtnTextCancel}>Cancelar</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={handleConfirmColor} style={styles.modalBtnConfirm}>
|
||||
<Text style={styles.modalBtnTextConfirm}>Confirmar</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</KeyboardAvoidingView>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
<SafeAreaView style={styles.safe}>
|
||||
<ScrollView showsVerticalScrollIndicator={false} keyboardShouldPersistTaps="handled">
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
@@ -150,7 +177,7 @@ function handleOpenColorPicker(): void {
|
||||
<View style={styles.colorPreviewRow}>
|
||||
<View style={[styles.colorSquare, { backgroundColor: selectedColor }]} />
|
||||
<Text style={styles.hexValue}>{hexInput}</Text>
|
||||
<TouchableOpacity><Ionicons name="pencil-outline" size={18} color={colors.textSecondary} /></TouchableOpacity>
|
||||
<TouchableOpacity onPress={handleOpenColorPicker}><Ionicons name="pencil-outline" size={18} color={colors.textSecondary} /></TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.colorPalette}>
|
||||
{PRESET_COLORS.map((c) => (
|
||||
@@ -318,6 +345,7 @@ function handleOpenColorPicker(): void {
|
||||
/>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -365,4 +393,15 @@ const styles = StyleSheet.create({
|
||||
resultDot: { width: 8, height: 8, borderRadius: radius.full },
|
||||
resultPct: { fontFamily: typography.fontFamily.ui, fontSize: typography.fontSize.sm, fontWeight: typography.fontWeight.bold, color: colors.accent },
|
||||
footer: { padding: spacing[5], borderTopWidth: 1, borderTopColor: colors.border, backgroundColor: colors.bgBase },
|
||||
// Modal styles
|
||||
modalOverlay: { flex: 1, backgroundColor: 'rgba(0, 0, 0, 0.5)', justifyContent: 'center', alignItems: 'center' },
|
||||
modalContent: { width: '85%', maxWidth: 320 },
|
||||
modalCard: { backgroundColor: colors.bgSurface, borderRadius: radius.lg, padding: spacing[5], gap: spacing[4] },
|
||||
modalTitle: { fontFamily: typography.fontFamily.ui, fontSize: typography.fontSize.base, fontWeight: typography.fontWeight.semibold, color: colors.textPrimary },
|
||||
modalInput: { backgroundColor: colors.bgBase, borderWidth: 1, borderColor: colors.border, borderRadius: radius.md, paddingHorizontal: spacing[3], paddingVertical: spacing[2], fontFamily: typography.fontFamily.mono, fontSize: typography.fontSize.base, color: colors.textPrimary },
|
||||
modalButtons: { flexDirection: 'row', gap: spacing[3] },
|
||||
modalBtnCancel: { flex: 1, backgroundColor: colors.bgHover, paddingVertical: spacing[3], borderRadius: radius.md, alignItems: 'center' },
|
||||
modalBtnTextCancel: { fontFamily: typography.fontFamily.ui, fontSize: typography.fontSize.sm, fontWeight: typography.fontWeight.semibold, color: colors.textPrimary },
|
||||
modalBtnConfirm: { flex: 1, backgroundColor: colors.accent, paddingVertical: spacing[3], borderRadius: radius.md, alignItems: 'center' },
|
||||
modalBtnTextConfirm: { fontFamily: typography.fontFamily.ui, fontSize: typography.fontSize.sm, fontWeight: typography.fontWeight.semibold, color: colors.bgBase },
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user