mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 06:59:31 +01:00
refactor
This commit is contained in:
@@ -1,13 +1,16 @@
|
|||||||
import React, {useState} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
Modal,
|
Modal,
|
||||||
|
KeyboardAvoidingView,
|
||||||
|
Platform,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import {styles} from './styles';
|
import {styles} from './styles';
|
||||||
let scrollViewRef;
|
|
||||||
const deviceHeight = Dimensions.get('window').height;
|
const deviceHeight = Dimensions.get('window').height;
|
||||||
|
|
||||||
const getElevation = elevation => {
|
const getElevation = elevation => {
|
||||||
@@ -20,198 +23,276 @@ const getElevation = elevation => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const ActionSheet = ({
|
export default class ActionSheet extends Component {
|
||||||
ref,
|
constructor(props) {
|
||||||
children = <View />,
|
super(props);
|
||||||
animated = true,
|
this.state = {
|
||||||
animationType = 'fade',
|
modalVisible: false,
|
||||||
closeOnPressBack = true,
|
scrollable: false,
|
||||||
gestureEnabled = true,
|
layoutHasCalled: false,
|
||||||
bounceOnOpen = true,
|
};
|
||||||
bounceOffset = 20,
|
this.customComponentHeight;
|
||||||
springOffset = 50,
|
this.prevScroll;
|
||||||
elevation = 5,
|
this.scrollAnimationEndValue;
|
||||||
initialOffsetFromBottom = 0.6,
|
this.hasBounced;
|
||||||
indicatorColor = 'gray',
|
this.scrollViewRef;
|
||||||
customStyles = {backgroundColor: 'white'},
|
}
|
||||||
overlayColor = 'rgba(0,0,0,0.3)',
|
|
||||||
onClose = () => {},
|
|
||||||
onOpen = () => {},
|
|
||||||
}) => {
|
|
||||||
const [modalVisible, setModalVisible] = useState(false);
|
|
||||||
const [scrollable, setScrollable] = useState(false);
|
|
||||||
const [layoutHasCalled, setLayoutHasCalled] = useState(false);
|
|
||||||
|
|
||||||
ActionSheet.customComponentHeight;
|
_setModalVisible = () => {
|
||||||
ActionSheet.prevScroll;
|
if (!this.state.modalVisible) {
|
||||||
ActionSheet.scrollAnimationEndValue;
|
this.setState({
|
||||||
ActionSheet.hasBounced;
|
modalVisible: true,
|
||||||
|
scrollable: this.props.gestureEnabled,
|
||||||
const _setModalVisible = () => {
|
});
|
||||||
if (!modalVisible) {
|
|
||||||
setModalVisible(true);
|
|
||||||
if (gestureEnabled) {
|
|
||||||
setScrollable(true);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_hideModal();
|
this._hideModal();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _hideModal = () => {
|
_hideModal = () => {
|
||||||
_scrollTo(0);
|
this._scrollTo(0);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLayoutHasCalled(false);
|
this.setState(
|
||||||
setModalVisible(false);
|
{
|
||||||
ActionSheet.customComponentHeight = null;
|
modalVisible: false,
|
||||||
ActionSheet.prevScroll = null;
|
layoutHasCalled: false,
|
||||||
ActionSheet.scrollAnimationEndValue = null;
|
},
|
||||||
ActionSheet.hasBounced = null;
|
() => {
|
||||||
if (typeof onClose === 'function') onClose();
|
if (typeof this.props.onClose === 'function') this.props.onClose();
|
||||||
|
},
|
||||||
|
);
|
||||||
}, 150);
|
}, 150);
|
||||||
};
|
};
|
||||||
|
|
||||||
const _showModal = event => {
|
_showModal = event => {
|
||||||
if (layoutHasCalled) {
|
let {gestureEnabled, bounceOffset, initialOffsetFromBottom} = this.props;
|
||||||
|
let addFactor = deviceHeight * 0.1;
|
||||||
|
let height = event.nativeEvent.layout.height;
|
||||||
|
console.log('layout called again');
|
||||||
|
if (this.state.layoutHasCalled) {
|
||||||
|
let diff;
|
||||||
|
if (height > this.customComponentHeight) {
|
||||||
|
diff = height - this.customComponentHeight;
|
||||||
|
this._scrollTo(this.prevScroll + diff);
|
||||||
|
console.log(this.prevScroll);
|
||||||
|
this.customComponentHeight = height;
|
||||||
|
} else {
|
||||||
|
diff = this.customComponentHeight - height;
|
||||||
|
this._scrollTo(this.prevScroll - diff);
|
||||||
|
this.customComponentHeight = height;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
ActionSheet.customComponentHeight = event.nativeEvent.layout.height;
|
this.customComponentHeight = height;
|
||||||
let addFactor = deviceHeight * 0.1;
|
|
||||||
_scrollTo(
|
this._scrollTo(
|
||||||
gestureEnabled
|
gestureEnabled
|
||||||
? ActionSheet.customComponentHeight * initialOffsetFromBottom +
|
? this.customComponentHeight * initialOffsetFromBottom +
|
||||||
addFactor +
|
addFactor +
|
||||||
bounceOffset
|
bounceOffset
|
||||||
: ActionSheet.customComponentHeight + bounceOffset,
|
: this.customComponentHeight + bounceOffset,
|
||||||
);
|
);
|
||||||
|
this.setState({
|
||||||
setLayoutHasCalled(true);
|
layoutHasCalled: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onScrollBeginDrag = event => {
|
_onScrollBeginDrag = event => {
|
||||||
let verticalOffset = event.nativeEvent.contentOffset.y;
|
let verticalOffset = event.nativeEvent.contentOffset.y;
|
||||||
ActionSheet.prevScroll = verticalOffset;
|
|
||||||
|
this.prevScroll = verticalOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onScrollEndDrag = event => {
|
_onScrollEndDrag = event => {
|
||||||
|
let {springOffset} = this.props;
|
||||||
|
|
||||||
let verticalOffset = event.nativeEvent.contentOffset.y;
|
let verticalOffset = event.nativeEvent.contentOffset.y;
|
||||||
|
|
||||||
if (ActionSheet.prevScroll < verticalOffset) {
|
if (this.prevScroll < verticalOffset) {
|
||||||
if (verticalOffset - ActionSheet.prevScroll > springOffset * 0.75) {
|
if (verticalOffset - this.prevScroll > springOffset * 0.75) {
|
||||||
let addFactor = deviceHeight * 0.1;
|
let addFactor = deviceHeight * 0.1;
|
||||||
_scrollTo(ActionSheet.customComponentHeight + addFactor);
|
this._scrollTo(this.customComponentHeight + addFactor);
|
||||||
} else {
|
} else {
|
||||||
_scrollTo(ActionSheet.prevScroll);
|
this._scrollTo(this.prevScroll);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ActionSheet.prevScroll - verticalOffset > springOffset) {
|
if (this.prevScroll - verticalOffset > springOffset) {
|
||||||
_hideModal();
|
this._hideModal();
|
||||||
} else {
|
} else {
|
||||||
_scrollTo(ActionSheet.prevScroll);
|
this._scrollTo(this.prevScroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _scrollTo = (y, bouncing) => {
|
_scrollTo = (y, bouncing) => {
|
||||||
|
let {bounceOffset, bounceOnOpen} = this.props;
|
||||||
|
|
||||||
|
this.hasBounced = false;
|
||||||
if (!bouncing && bounceOnOpen) {
|
if (!bouncing && bounceOnOpen) {
|
||||||
ActionSheet.scrollAnimationEndValue = y + bounceOffset;
|
this.scrollAnimationEndValue = y + bounceOffset;
|
||||||
} else {
|
} else {
|
||||||
ActionSheet.scrollAnimationEndValue = y;
|
this.scrollAnimationEndValue = y;
|
||||||
}
|
}
|
||||||
ActionSheet.hasBounced = false;
|
|
||||||
scrollViewRef.scrollTo({
|
this.scrollViewRef.scrollTo({
|
||||||
x: 0,
|
x: 0,
|
||||||
y: ActionSheet.scrollAnimationEndValue,
|
y: this.scrollAnimationEndValue,
|
||||||
animated: true,
|
animated: true,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onTouchMove = () => {
|
_onTouchMove = () => {
|
||||||
setScrollable(false);
|
this._hideModal();
|
||||||
|
this.setState({
|
||||||
|
scrollable: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onTouchStart = () => {
|
_onTouchStart = () => {
|
||||||
setScrollable(false);
|
this._hideModal();
|
||||||
|
this.setState({
|
||||||
|
scrollable: false,
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onTouchEnd = () => {
|
_onTouchEnd = () => {
|
||||||
if (gestureEnabled) {
|
if (this.props.gestureEnabled) {
|
||||||
setScrollable(true);
|
this.setState({
|
||||||
|
scrollable: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _onScrollEndAnimation = () => {
|
_onScrollEndAnimation = event => {
|
||||||
if (!ActionSheet.hasBounced) {
|
this.prevScroll = event.nativeEvent.contentOffset.y;
|
||||||
_scrollTo(ActionSheet.scrollAnimationEndValue - bounceOffset, true);
|
|
||||||
ActionSheet.hasBounced = true;
|
let {bounceOffset, bounceOnOpen} = this.props;
|
||||||
|
if (!this.hasBounced && bounceOnOpen) {
|
||||||
|
this._scrollTo(this.scrollAnimationEndValue - bounceOffset, true);
|
||||||
|
this.hasBounced = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
render() {
|
||||||
<Modal
|
let {scrollable, modalVisible} = this.state;
|
||||||
ref={ref}
|
let {
|
||||||
visible={modalVisible}
|
animationType,
|
||||||
animationType={animationType}
|
animated,
|
||||||
animated={animated}
|
onOpen,
|
||||||
onShow={() => onOpen}
|
closeOnPressBack,
|
||||||
onRequestClose={() => {
|
overlayColor,
|
||||||
if (closeOnPressBack) _hideModal();
|
bounceOnOpen,
|
||||||
}}
|
gestureEnabled,
|
||||||
transparent={true}>
|
elevation,
|
||||||
<View style={[styles.parentContainer, {backgroundColor: overlayColor}]}>
|
indicatorColor,
|
||||||
<ScrollView
|
children,
|
||||||
bounces={false}
|
customStyles,
|
||||||
ref={ref => (scrollViewRef = ref)}
|
} = this.props;
|
||||||
showsVerticalScrollIndicator={false}
|
|
||||||
scrollEnabled={scrollable}
|
return (
|
||||||
onScrollBeginDrag={_onScrollBeginDrag}
|
<Modal
|
||||||
onScrollEndDrag={_onScrollEndDrag}
|
visible={modalVisible}
|
||||||
onMomentumScrollEnd={() => {
|
animationType={animationType}
|
||||||
if (bounceOnOpen) {
|
animated={animated}
|
||||||
_onScrollEndAnimation();
|
onShow={() => onOpen}
|
||||||
}
|
onRequestClose={() => {
|
||||||
}}
|
if (closeOnPressBack) this._hideModal();
|
||||||
onScrollAnimationEnd={_onScrollEndAnimation}
|
}}
|
||||||
onTouchEnd={_onTouchEnd}
|
transparent={true}>
|
||||||
overScrollMode="always"
|
<View style={[styles.parentContainer, {backgroundColor: overlayColor}]}>
|
||||||
style={[styles.scrollview]}>
|
<KeyboardAvoidingView
|
||||||
<View
|
|
||||||
onTouchMove={_onTouchMove}
|
|
||||||
onTouchStart={_onTouchStart}
|
|
||||||
onTouchEnd={_onTouchEnd}
|
|
||||||
style={{
|
style={{
|
||||||
height: deviceHeight * 1.1,
|
|
||||||
width: '100%',
|
width: '100%',
|
||||||
}}>
|
}}
|
||||||
<TouchableOpacity
|
enabled={Platform.OS === 'ios' ? true : false}
|
||||||
onPress={_hideModal}
|
behavior="position">
|
||||||
onLongPress={_hideModal}
|
<ScrollView
|
||||||
style={{
|
bounces={false}
|
||||||
height: deviceHeight,
|
ref={ref => (this.scrollViewRef = ref)}
|
||||||
width: '100%',
|
showsVerticalScrollIndicator={false}
|
||||||
}}
|
scrollEnabled={scrollable}
|
||||||
/>
|
onScrollBeginDrag={this._onScrollBeginDrag}
|
||||||
</View>
|
onScrollEndDrag={this._onScrollEndDrag}
|
||||||
<View
|
onMomentumScrollEnd={this._onScrollEndAnimation}
|
||||||
onLayout={_showModal}
|
onScrollAnimationEnd={this._onScrollEndAnimation}
|
||||||
style={[
|
onTouchEnd={this._onTouchEnd}
|
||||||
styles.container,
|
overScrollMode="always"
|
||||||
customStyles,
|
style={[styles.scrollview]}>
|
||||||
{...getElevation(elevation)},
|
|
||||||
]}>
|
|
||||||
{gestureEnabled ? (
|
|
||||||
<View
|
<View
|
||||||
style={[styles.indicator, {backgroundColor: indicatorColor}]}
|
onTouchMove={this._onTouchMove}
|
||||||
/>
|
onTouchStart={this._onTouchStart}
|
||||||
) : null}
|
onTouchEnd={this._onTouchEnd}
|
||||||
|
style={{
|
||||||
|
height: deviceHeight * 1.1,
|
||||||
|
width: '100%',
|
||||||
|
}}>
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={this._hideModal}
|
||||||
|
onLongPress={this._hideModal}
|
||||||
|
style={{
|
||||||
|
height: deviceHeight,
|
||||||
|
width: '100%',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View
|
||||||
|
onLayout={this._showModal}
|
||||||
|
style={[
|
||||||
|
styles.container,
|
||||||
|
customStyles,
|
||||||
|
{...getElevation(elevation)},
|
||||||
|
]}>
|
||||||
|
{gestureEnabled ? (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
styles.indicator,
|
||||||
|
{backgroundColor: indicatorColor},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</KeyboardAvoidingView>
|
||||||
</Modal>
|
</View>
|
||||||
);
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActionSheet.defaultProps = {
|
||||||
|
children: <View />,
|
||||||
|
animated: true,
|
||||||
|
animationType: 'fade',
|
||||||
|
closeOnPressBack: true,
|
||||||
|
gestureEnabled: true,
|
||||||
|
bounceOnOpen: true,
|
||||||
|
bounceOffset: 20,
|
||||||
|
springOffset: 50,
|
||||||
|
elevation: 5,
|
||||||
|
initialOffsetFromBottom: 0.6,
|
||||||
|
indicatorColor: 'gray',
|
||||||
|
customStyles: {},
|
||||||
|
overlayColor: 'rgba(0,0,0,0.3)',
|
||||||
|
onClose: () => {},
|
||||||
|
onOpen: () => {},
|
||||||
|
};
|
||||||
|
ActionSheet.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
animated: PropTypes.bool,
|
||||||
|
animationType: PropTypes.oneOf(['none', 'slide', 'fade']),
|
||||||
|
closeOnPressBack: PropTypes.bool,
|
||||||
|
gestureEnabled: PropTypes.bool,
|
||||||
|
bounceOnOpen: PropTypes.bool,
|
||||||
|
bounceOffset: PropTypes.number,
|
||||||
|
springOffset: PropTypes.number,
|
||||||
|
elevation: PropTypes.number,
|
||||||
|
initialOffsetFromBottom: PropTypes.number,
|
||||||
|
indicatorColor: PropTypes.string,
|
||||||
|
customStyles: PropTypes.object,
|
||||||
|
overlayColor: PropTypes.string,
|
||||||
|
onClose: PropTypes.func,
|
||||||
|
onOpen: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ActionSheet;
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, {useState} from 'react';
|
import React, {useState, useEffect} from 'react';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
@@ -28,7 +28,7 @@ const h = Dimensions.get('window').height;
|
|||||||
let tagsInputRef;
|
let tagsInputRef;
|
||||||
export const ActionSheetComponent = ({
|
export const ActionSheetComponent = ({
|
||||||
close = () => {},
|
close = () => {},
|
||||||
item = {},
|
item,
|
||||||
setWillRefresh = value => {},
|
setWillRefresh = value => {},
|
||||||
hasColors = false,
|
hasColors = false,
|
||||||
hasTags = false,
|
hasTags = false,
|
||||||
@@ -39,6 +39,10 @@ export const ActionSheetComponent = ({
|
|||||||
const [focused, setFocused] = useState(false);
|
const [focused, setFocused] = useState(false);
|
||||||
const [note, setNote] = useState(item ? item : {});
|
const [note, setNote] = useState(item ? item : {});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setNote({...item});
|
||||||
|
}, [item]);
|
||||||
|
|
||||||
let tagToAdd = null;
|
let tagToAdd = null;
|
||||||
let backPressCount = 0;
|
let backPressCount = 0;
|
||||||
|
|
||||||
@@ -257,6 +261,10 @@ export const ActionSheetComponent = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
|
onLayout={() => {
|
||||||
|
console.log(item);
|
||||||
|
setNote({...item});
|
||||||
|
}}
|
||||||
style={{
|
style={{
|
||||||
paddingBottom: 15,
|
paddingBottom: 15,
|
||||||
backgroundColor: colors.bg,
|
backgroundColor: colors.bg,
|
||||||
|
|||||||
Reference in New Issue
Block a user