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',
registryVisible: 'Visible in Registry',
editImage: 'Edit Image',
editDetails: 'Edit Details',
editDetails: 'Edit Details',
},
{
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 MatIcons from 'react-native-vector-icons/MaterialCommunityIcons';
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 { Menu, MenuOptions, MenuOption, MenuTrigger } from 'react-native-popup-menu';
import { Colors } from 'constants/Colors';
@ -17,7 +19,16 @@ export function Profile() {
try {
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 });
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) {
console.log(err);
@ -59,25 +70,25 @@ const triggerStyles = {
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}>
<Menu>
<MenuTrigger customStyles={styles.trigger}>
<View style={styles.edit}>
<Text style={styles.editLabel}>{ state.strings.edit }</Text>
<MatIcons name="square-edit-outline" size={14} color={Colors.linkText} />
</View>
<View style={styles.edit}>
<Text style={styles.editLabel}>{ state.strings.edit }</Text>
<MatIcons name="square-edit-outline" size={14} color={Colors.linkText} />
</View>
</MenuTrigger>
<MenuOptions style={styles.options}>
<MenuOption onSelect={() => alert(`image`)}>
<MenuOptions optionsContainerStyle={{ width: 'auto' }} style={styles.options}>
<MenuOption onSelect={onGallery}>
<Text style={styles.option}>{ state.strings.editImage }</Text>
</MenuOption>
<MenuOption onSelect={() => alert(`details`)}>
<MenuOption onSelect={actions.showDetails}>
<Text style={styles.option}>{ state.strings.editDetails }</Text>
</MenuOption>
</MenuOptions>
@ -126,6 +137,70 @@ const triggerStyles = {
</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>
);
}

View File

@ -5,20 +5,21 @@ export const styles = StyleSheet.create({
content: {
width: '100%',
height: '100%',
display: 'flex',
backgroundColor: Colors.screenBase,
},
details: {
width: '100%',
position: 'relative',
top: -32,
minHeight: 32,
backgroundColor: 'yellow',
borderTopRightRadius: 32,
borderTopLeftRadius: 32,
backgroundColor: Colors.screenBase,
borderTopWidth: 1,
borderColor: Colors.areaBorder,
borderLeftWidth: 0.2,
borderRightWidth: 0.2,
paddingLeft: 1,
paddingRight: 1,
},
control: {
position: 'absolute',
@ -31,8 +32,8 @@ export const styles = StyleSheet.create({
borderTopLeftRadius: 8,
borderTopRightRadius: 8,
backgroundColor: Colors.screenBase,
paddingLeft: 8,
paddingRight: 8,
paddingLeft: 16,
paddingRight: 16,
paddingTop: 2,
display: 'flex',
flexDirection: 'row',
@ -45,7 +46,6 @@ export const styles = StyleSheet.create({
},
editLabel: {
color: Colors.text,
paddingLeft: 8,
paddingRight: 8,
paddingTop: 2,
fontSize: 16,
@ -139,7 +139,9 @@ export const styles = StyleSheet.create({
},
},
options: {
backgroundColor: Colors.areaBase,
backgroundColor: Colors.areaBase,
borderWidth: 0.2,
borderColor: Colors.areaBorder,
},
option: {
padding: 4,
@ -147,6 +149,67 @@ export const styles = StyleSheet.create({
backgroundColor: Colors.areaBase,
fontFamily: 'roboto',
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,
location: null,
description: null,
imageWidth: null,
imageHeight: null,
detailWidth: null,
details: false,
detailName: '',
});
const dimensions = useWindowDimensions();
@ -29,10 +34,10 @@ export function useProfile() {
useEffect(() => {
const { width, height } = dimensions;
if (height > width) {
updateState({ width, height: width });
updateState({ imageWidth: width, imageHeight: width, detailWidth: width + 2 });
}
else {
updateState({ width: height, height });
updateState({ imageWidth: height, imageHeight, detailWidth: width + 2 });
}
}, [dimensions]);
@ -50,8 +55,33 @@ export function useProfile() {
const actions = {
setVisible: async (searchable) => {
await account.actions.setSearchable(searchable);
updateState({ searchable });
const cur = state.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'}
spellCheck={false}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
onChangeText={actions.setSealDelete}
@ -542,7 +542,7 @@ export function Settings() {
autoComplete={'off'}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
@ -559,7 +559,7 @@ export function Settings() {
spellCheck={false}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
@ -616,7 +616,7 @@ export function Settings() {
autoCapitalize={'none'}
spellCheck={false}
inputStyles={styles.floatingInput}
labelStyles={styles.floatingLable}
labelStyles={styles.floatingLabel}
customLabelStyles={styles.floatingCustomLabel}
containerStyles={styles.floatingContainer}
onChangeText={actions.setConfirm}