refactor profile screen continued

This commit is contained in:
balzack 2023-09-11 00:41:57 -07:00
parent 1c171d0372
commit 81a222a18f
5 changed files with 195 additions and 27 deletions

View File

@ -80,7 +80,7 @@ const Strings = [
description: 'Description', description: 'Description',
registryVisible: 'Visible in Registry', registryVisible: 'Visible in Registry',
editImage: 'Edit Image', editImage: 'Edit Image',
editDetails: 'Edit Details', editDetails: 'Edit Details',
}, },
{ {
visibleRegistry: 'Visible dans le Registre', visibleRegistry: 'Visible dans le Registre',

View File

@ -2,6 +2,8 @@ import { ActivityIndicator, KeyboardAvoidingView, Image, Modal, View, Switch, Te
import AntIcons from 'react-native-vector-icons/AntDesign'; import AntIcons from 'react-native-vector-icons/AntDesign';
import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import ImagePicker from 'react-native-image-crop-picker' import ImagePicker from 'react-native-image-crop-picker'
import { BlurView } from "@react-native-community/blur";
import { FloatingLabelInput } from 'react-native-floating-label-input';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context'; import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { Menu, MenuOptions, MenuOption, MenuTrigger } from 'react-native-popup-menu'; import { Menu, MenuOptions, MenuOption, MenuTrigger } from 'react-native-popup-menu';
import { Colors } from 'constants/Colors'; import { Colors } from 'constants/Colors';
@ -17,7 +19,16 @@ export function Profile() {
try { try {
const full = await ImagePicker.openPicker({ mediaType: 'photo', width: 256, height: 256 }); const full = await ImagePicker.openPicker({ mediaType: 'photo', width: 256, height: 256 });
const crop = await ImagePicker.openCropper({ path: full.path, width: 256, height: 256, cropperCircleOverlay: true, includeBase64: true }); const crop = await ImagePicker.openCropper({ path: full.path, width: 256, height: 256, cropperCircleOverlay: true, includeBase64: true });
await actions.setProfileImage(crop.data); try {
await actions.setProfileImage(crop.data);
}
catch (err) {
console.log(err);
Alert.alert(
state.strings.error,
state.strings.tryAgain,
);
}
} }
catch (err) { catch (err) {
console.log(err); console.log(err);
@ -59,25 +70,25 @@ const triggerStyles = {
return ( return (
<ScrollView style={styles.content}> <ScrollView style={styles.content} contentContainerStyle={{ display: 'flex', alignItems: 'center' }}>
<Image source={state.imageSource} style={{ width: state.width, height: state.height, alignSelf: 'center' }} resizeMode={'contain'} /> <Image source={state.imageSource} style={{ width: state.imageWidth, height: state.imageHeight, alignSelf: 'center' }} resizeMode={'contain'} />
<View style={styles.details}> <View style={{ ...styles.details, width: state.detailWidth }}>
<View style={styles.control}> <View style={styles.control}>
<Menu> <Menu>
<MenuTrigger customStyles={styles.trigger}> <MenuTrigger customStyles={styles.trigger}>
<View style={styles.edit}> <View style={styles.edit}>
<Text style={styles.editLabel}>{ state.strings.edit }</Text> <Text style={styles.editLabel}>{ state.strings.edit }</Text>
<MatIcons name="square-edit-outline" size={14} color={Colors.linkText} /> <MatIcons name="square-edit-outline" size={14} color={Colors.linkText} />
</View> </View>
</MenuTrigger> </MenuTrigger>
<MenuOptions style={styles.options}> <MenuOptions optionsContainerStyle={{ width: 'auto' }} style={styles.options}>
<MenuOption onSelect={() => alert(`image`)}> <MenuOption onSelect={onGallery}>
<Text style={styles.option}>{ state.strings.editImage }</Text> <Text style={styles.option}>{ state.strings.editImage }</Text>
</MenuOption> </MenuOption>
<MenuOption onSelect={() => alert(`details`)}> <MenuOption onSelect={actions.showDetails}>
<Text style={styles.option}>{ state.strings.editDetails }</Text> <Text style={styles.option}>{ state.strings.editDetails }</Text>
</MenuOption> </MenuOption>
</MenuOptions> </MenuOptions>
@ -126,6 +137,70 @@ const triggerStyles = {
</View> </View>
</View> </View>
<Modal
animationType="fade"
transparent={true}
visible={state.details}
supportedOrientations={['portrait', 'landscape']}
onRequestClose={actions.hideDetails}
>
<BlurView style={styles.modalOverlay} blurType={Colors.overlay} blurAmount={2} reducedTransparencyFallbackColor="black">
<View style={styles.modalContainer}>
<View style={styles.modalClose}>
<TouchableOpacity style={styles.dismissButton} activeOpacity={1} onPress={actions.hideDetails}>
<MatIcons name="close" size={20} color={Colors.descriptionText} />
</TouchableOpacity>
</View>
<Text style={styles.modalHeader}>{ state.strings.editDetails }</Text>
<View style={styles.modalInput}>
<FloatingLabelInput
label={state.strings.name}
value={state.detailName}
autoCapitalize={'none'}
spellCheck={false}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
onChangeText={actions.setDetailName}
/>
</View>
<View style={styles.modalInput}>
<FloatingLabelInput
label={state.strings.location}
value={state.detailLocation}
autoCapitalize={'none'}
spellCheck={false}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
onChangeText={actions.setDetailLocation}
/>
</View>
<View style={styles.modalInput}>
<FloatingLabelInput
label={state.strings.description}
value={state.detailDescription}
autoCapitalize={'none'}
spellCheck={false}
multiline={true}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
onChangeText={actions.setDetailDescription}
/>
</View>
</View>
</BlurView>
</Modal>
</ScrollView> </ScrollView>
); );
} }

View File

@ -5,20 +5,21 @@ export const styles = StyleSheet.create({
content: { content: {
width: '100%', width: '100%',
height: '100%', height: '100%',
display: 'flex',
backgroundColor: Colors.screenBase, backgroundColor: Colors.screenBase,
}, },
details: { details: {
width: '100%',
position: 'relative', position: 'relative',
top: -32, top: -32,
minHeight: 32, minHeight: 32,
backgroundColor: 'yellow',
borderTopRightRadius: 32, borderTopRightRadius: 32,
borderTopLeftRadius: 32, borderTopLeftRadius: 32,
backgroundColor: Colors.screenBase, backgroundColor: Colors.screenBase,
borderTopWidth: 1, borderTopWidth: 1,
borderColor: Colors.areaBorder, borderColor: Colors.areaBorder,
borderLeftWidth: 0.2,
borderRightWidth: 0.2,
paddingLeft: 1,
paddingRight: 1,
}, },
control: { control: {
position: 'absolute', position: 'absolute',
@ -31,8 +32,8 @@ export const styles = StyleSheet.create({
borderTopLeftRadius: 8, borderTopLeftRadius: 8,
borderTopRightRadius: 8, borderTopRightRadius: 8,
backgroundColor: Colors.screenBase, backgroundColor: Colors.screenBase,
paddingLeft: 8, paddingLeft: 16,
paddingRight: 8, paddingRight: 16,
paddingTop: 2, paddingTop: 2,
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
@ -45,7 +46,6 @@ export const styles = StyleSheet.create({
}, },
editLabel: { editLabel: {
color: Colors.text, color: Colors.text,
paddingLeft: 8,
paddingRight: 8, paddingRight: 8,
paddingTop: 2, paddingTop: 2,
fontSize: 16, fontSize: 16,
@ -139,7 +139,9 @@ export const styles = StyleSheet.create({
}, },
}, },
options: { options: {
backgroundColor: Colors.areaBase, backgroundColor: Colors.areaBase,
borderWidth: 0.2,
borderColor: Colors.areaBorder,
}, },
option: { option: {
padding: 4, padding: 4,
@ -147,6 +149,67 @@ export const styles = StyleSheet.create({
backgroundColor: Colors.areaBase, backgroundColor: Colors.areaBase,
fontFamily: 'roboto', fontFamily: 'roboto',
fontSize: 16, fontSize: 16,
textAlign: 'center',
},
modalOverlay: {
display: 'flex',
width: '100%',
height: '100%',
alignItems: 'center',
justifyContent: 'center',
},
modalContainer: {
backgroundColor: Colors.modalBase,
width: '80%',
maxWidth: 400,
display: 'flex',
alignItems: 'center',
borderRadius: 8,
},
modalClose: {
position: 'absolute',
width: '100%',
display: 'flex',
alignItems: 'flex-end',
},
dismissButton: {
padding: 12,
},
modalHeader: {
fontSize: 18,
paddingTop: 16,
color: Colors.labelText,
fontFamily: 'Roboto',
},
modalInput: {
marginRight: 16,
marginLeft: 16,
marginTop: 8,
marginBottom: 8,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
},
floatingInput: {
color: Colors.inputText,
paddingTop: 20,
paddingBottom: 4,
},
floatingLabel: {
color: Colors.text,
},
floatingCustomLabel: {
colorFocused: Colors.inputPlaceholder,
colorBlurred: Colors.inputPlaceholder,
fontSizeFocused: 12,
},
floatingContainer: {
paddingHorizontal: 12,
backgroundColor: Colors.inputBase,
borderRadius: 8,
minHeight: 48,
maxHeight: 128,
}, },
}); });

View File

@ -16,6 +16,11 @@ export function useProfile() {
username: null, username: null,
location: null, location: null,
description: null, description: null,
imageWidth: null,
imageHeight: null,
detailWidth: null,
details: false,
detailName: '',
}); });
const dimensions = useWindowDimensions(); const dimensions = useWindowDimensions();
@ -29,10 +34,10 @@ export function useProfile() {
useEffect(() => { useEffect(() => {
const { width, height } = dimensions; const { width, height } = dimensions;
if (height > width) { if (height > width) {
updateState({ width, height: width }); updateState({ imageWidth: width, imageHeight: width, detailWidth: width + 2 });
} }
else { else {
updateState({ width: height, height }); updateState({ imageWidth: height, imageHeight, detailWidth: width + 2 });
} }
}, [dimensions]); }, [dimensions]);
@ -50,8 +55,33 @@ export function useProfile() {
const actions = { const actions = {
setVisible: async (searchable) => { setVisible: async (searchable) => {
await account.actions.setSearchable(searchable); const cur = state.searchable;
updateState({ searchable }); try {
updateState({ searchable });
await account.actions.setSearchable(searchable);
}
catch(err) {
updateState({ searchable: cur });
throw err;
}
},
setProfileImage: async (data) => {
await profile.actions.setProfileImage(data);
},
showDetails: () => {
updateState({ details: true, detailName: '', detailLocation: '', detailDescription: '' });
},
hideDetails: () => {
updateState({ details: false });
},
setDetailName: (detailName) => {
updateState({ detailName });
},
setDetailLocation: (detailLocation) => {
updateState({ detailLocation });
},
setDetailDescription: (detailDescription) => {
updateState({ detailDescription });
}, },
}; };

View File

@ -440,7 +440,7 @@ export function Settings() {
autoCapitalize={'none'} autoCapitalize={'none'}
spellCheck={false} spellCheck={false}
inputStyles={styles.floatingInput} inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable} labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel} customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer} containerStyles={styles.floatingContainer}
onChangeText={actions.setSealDelete} onChangeText={actions.setSealDelete}
@ -542,7 +542,7 @@ export function Settings() {
autoComplete={'off'} autoComplete={'off'}
inputStyles={styles.floatingInput} inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable} labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel} customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer} containerStyles={styles.floatingContainer}
@ -559,7 +559,7 @@ export function Settings() {
spellCheck={false} spellCheck={false}
inputStyles={styles.floatingInput} inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable} labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel} customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer} containerStyles={styles.floatingContainer}
@ -616,7 +616,7 @@ export function Settings() {
autoCapitalize={'none'} autoCapitalize={'none'}
spellCheck={false} spellCheck={false}
inputStyles={styles.floatingInput} inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable} labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel} customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer} containerStyles={styles.floatingContainer}
onChangeText={actions.setConfirm} onChangeText={actions.setConfirm}