some fixes for tablet & iOS

This commit is contained in:
ammarahm-ed
2020-03-23 15:05:02 +05:00
parent d347b1dc8d
commit 61aee789f1
5 changed files with 178 additions and 81 deletions

View File

@@ -1,4 +1,4 @@
import React, {createRef, useEffect} from 'react'; import React, {createRef, useEffect, useState} from 'react';
import {Platform, StatusBar, View} from 'react-native'; import {Platform, StatusBar, View} from 'react-native';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import {Menu} from './src/components/Menu'; import {Menu} from './src/components/Menu';
@@ -8,6 +8,11 @@ import NavigationService, {
AppContainer, AppContainer,
} from './src/services/NavigationService'; } from './src/services/NavigationService';
import Editor from './src/views/Editor'; import Editor from './src/views/Editor';
import {eSubscribeEvent} from './src/services/eventManager';
import {
eOpenFullscreenEditor,
eCloseFullscreenEditor,
} from './src/services/events';
const editorRef = createRef(); const editorRef = createRef();
let outColors; let outColors;

View File

@@ -1,4 +1,4 @@
import React, {Component} from 'react'; import React, {Component, createRef} from 'react';
import { import {
View, View,
TouchableOpacity, TouchableOpacity,
@@ -8,11 +8,12 @@ import {
KeyboardAvoidingView, KeyboardAvoidingView,
Platform, Platform,
Animated, Animated,
DeviceEventEmitter,
} from 'react-native'; } from 'react-native';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {styles} from './styles'; import {styles} from './styles';
const deviceHeight = Dimensions.get('window').height; var deviceHeight = Dimensions.get('window').height;
const getElevation = elevation => { const getElevation = elevation => {
return { return {
@@ -31,6 +32,7 @@ const SUPPORTED_ORIENTATIONS = [
'landscape-left', 'landscape-left',
'landscape-right', 'landscape-right',
]; ];
export default class ActionSheet extends Component { export default class ActionSheet extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@@ -39,19 +41,31 @@ export default class ActionSheet extends Component {
scrollable: false, scrollable: false,
layoutHasCalled: false, layoutHasCalled: false,
}; };
this.containerOpacity = new Animated.Value(0);
this.transformValue = new Animated.Value(0); this.transformValue = new Animated.Value(0);
this.opacity = new Animated.Value(0); this.opacityValue = new Animated.Value(0);
this.customComponentHeight; this.customComponentHeight;
this.prevScroll; this.prevScroll;
this.scrollAnimationEndValue; this.scrollAnimationEndValue;
this.hasBounced; this.hasBounced;
this.scrollViewRef; this.scrollViewRef = createRef();
this.layoutHasCalled = false; this.layoutHasCalled = false;
this.isClosing = false; this.isClosing = false;
this.isRecoiling = false;
} }
waitAsync = ms =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});
/**
* Open/Close the ActionSheet
*/
_setModalVisible = () => { _setModalVisible = () => {
deviceHeight = Dimensions.get('window').height;
if (!this.state.modalVisible) { if (!this.state.modalVisible) {
this.setState({ this.setState({
modalVisible: true, modalVisible: true,
@@ -67,14 +81,12 @@ export default class ActionSheet extends Component {
if (this.isClosing) return; if (this.isClosing) return;
this.isClosing = true; this.isClosing = true;
Animated.parallel([
Animated.timing(this.transformValue, { Animated.timing(this.transformValue, {
toValue: this.customComponentHeight * 2, toValue: this.customComponentHeight * 2,
duration: animated ? closeAnimationDuration : 1, duration: animated ? closeAnimationDuration : 1,
useNativeDriver: true, useNativeDriver: true,
}), }).start(() => {
]).start(() => { this.scrollViewRef.current?.scrollTo({
this.scrollViewRef.scrollTo({
x: 0, x: 0,
y: 0, y: 0,
animated: false, animated: false,
@@ -92,7 +104,7 @@ export default class ActionSheet extends Component {
}); });
}; };
_showModal = event => { _showModal = async event => {
let { let {
gestureEnabled, gestureEnabled,
bounciness, bounciness,
@@ -102,6 +114,7 @@ export default class ActionSheet extends Component {
footerHeight, footerHeight,
footerAlwaysVisible, footerAlwaysVisible,
extraScroll, extraScroll,
openAnimationSpeed,
} = this.props; } = this.props;
let addFactor = deviceHeight * 0.1; let addFactor = deviceHeight * 0.1;
@@ -110,14 +123,12 @@ export default class ActionSheet extends Component {
let diff; let diff;
if (height > this.customComponentHeight) { if (height > this.customComponentHeight) {
diff = height - this.customComponentHeight; diff = height - this.customComponentHeight;
//this._scrollTo(this.prevScroll + diff + 15); this._scrollTo(this.prevScroll + diff);
this.customComponentHeight = height; this.customComponentHeight = height;
} else { } else {
diff = this.customComponentHeight - height; diff = this.customComponentHeight - height;
this._scrollTo(this.prevScroll - diff);
// this._scrollTo(this.prevScroll - diff - 7);
this.customComponentHeight = height; this.customComponentHeight = height;
} }
return; return;
@@ -127,54 +138,91 @@ export default class ActionSheet extends Component {
} else { } else {
this.customComponentHeight = height - footerHeight; this.customComponentHeight = height - footerHeight;
} }
if (this.customComponentHeight > deviceHeight) {
this.customComponentHeight =
(this.customComponentHeight -
(this.customComponentHeight - deviceHeight)) *
0.9;
}
let scrollOffset = gestureEnabled let scrollOffset = gestureEnabled
? this.customComponentHeight * initialOffsetFromBottom + ? this.customComponentHeight * initialOffsetFromBottom +
addFactor + addFactor +
extraScroll extraScroll
: this.customComponentHeight + addFactor + extraScroll; : this.customComponentHeight + addFactor + extraScroll;
this.scrollViewRef.scrollTo({ await this.waitAsync(50);
this.scrollViewRef.current.scrollTo({
x: 0, x: 0,
y: scrollOffset, y: scrollOffset,
animated: false, animated: false,
}); });
await this.waitAsync(20);
if (animated) { if (animated) {
this.transformValue.setValue(scrollOffset); this.transformValue.setValue(scrollOffset);
Animated.parallel([ this.opacityValue.setValue(1);
Animated.spring(this.transformValue, { Animated.spring(this.transformValue, {
toValue: 0, toValue: 0,
bounciness: bounceOnOpen ? bounciness : 1, bounciness: bounceOnOpen ? bounciness : 1,
speed: openAnimationSpeed,
useNativeDriver: true, useNativeDriver: true,
}).start(), }).start();
]).start(); }
if (!gestureEnabled) {
DeviceEventEmitter.emit('hasReachedTop');
} }
this.layoutHasCalled = true; this.layoutHasCalled = true;
} }
}; };
_onScrollBeginDrag = event => { _onScrollBegin = event => {
let verticalOffset = event.nativeEvent.contentOffset.y; let verticalOffset = event.nativeEvent.contentOffset.y;
this.prevScroll = verticalOffset; this.prevScroll = verticalOffset;
}; };
_onScrollEndDrag = event => { _onScrollEnd = async event => {
let {springOffset, extraScroll} = this.props; let {springOffset, extraScroll} = this.props;
let verticalOffset = event.nativeEvent.contentOffset.y; let verticalOffset = event.nativeEvent.contentOffset.y;
if (this.prevScroll < verticalOffset) { if (this.prevScroll < verticalOffset) {
if (this.isRecoiling) return;
if (verticalOffset - this.prevScroll > springOffset * 0.75) { if (verticalOffset - this.prevScroll > springOffset * 0.75) {
this.isRecoiling = true;
let addFactor = deviceHeight * 0.1; let addFactor = deviceHeight * 0.1;
this._scrollTo(this.customComponentHeight + addFactor + extraScroll);
let scrollValue = this.customComponentHeight + addFactor + extraScroll;
if (scrollValue > deviceHeight) {
scrollValue = (scrollValue - (scrollValue - deviceHeight)) * 1;
}
this._scrollTo(scrollValue);
await this.waitAsync(450);
this.isRecoiling = false;
DeviceEventEmitter.emit('hasReachedTop');
} else { } else {
this._scrollTo(this.prevScroll); this._scrollTo(this.prevScroll);
} }
} else { } else {
if (this.prevScroll - verticalOffset > springOffset) { if (this.prevScroll - verticalOffset > springOffset) {
if (this.isRecoiling) {
return;
}
this._hideModal(); this._hideModal();
} else { } else {
if (this.isRecoiling) {
return;
}
this.isRecoiling = true;
await this.waitAsync(450);
this.isRecoiling = false;
this._scrollTo(this.prevScroll); this._scrollTo(this.prevScroll);
} }
} }
@@ -182,7 +230,7 @@ export default class ActionSheet extends Component {
_scrollTo = y => { _scrollTo = y => {
this.scrollAnimationEndValue = y; this.scrollAnimationEndValue = y;
this.scrollViewRef.scrollTo({ this.scrollViewRef.current?.scrollTo({
x: 0, x: 0,
y: this.scrollAnimationEndValue, y: this.scrollAnimationEndValue,
animated: true, animated: true,
@@ -190,14 +238,18 @@ export default class ActionSheet extends Component {
}; };
_onTouchMove = () => { _onTouchMove = () => {
if (this.props.closeOnTouchBackdrop) {
this._hideModal(); this._hideModal();
}
this.setState({ this.setState({
scrollable: false, scrollable: false,
}); });
}; };
_onTouchStart = () => { _onTouchStart = () => {
if (this.props.closeOnTouchBackdrop) {
this._hideModal(); this._hideModal();
}
this.setState({ this.setState({
scrollable: false, scrollable: false,
}); });
@@ -211,11 +263,19 @@ export default class ActionSheet extends Component {
} }
}; };
_onRequestClose = () => {
if (this.props.closeOnPressBack) this._hideModal();
};
_onTouchBackdrop = () => {
if (this.props.closeOnTouchBackdrop) {
this._hideModal();
}
};
render() { render() {
let {scrollable, modalVisible} = this.state; let {scrollable, modalVisible} = this.state;
let { let {
onOpen, onOpen,
closeOnPressBack,
overlayColor, overlayColor,
gestureEnabled, gestureEnabled,
elevation, elevation,
@@ -237,30 +297,31 @@ export default class ActionSheet extends Component {
animationType="fade" animationType="fade"
supportedOrientations={SUPPORTED_ORIENTATIONS} supportedOrientations={SUPPORTED_ORIENTATIONS}
onShow={() => onOpen} onShow={() => onOpen}
onRequestClose={() => { onRequestClose={this._onRequestClose}
if (closeOnPressBack) this._hideModal();
}}
transparent={true}> transparent={true}>
<Animated.View style={[styles.parentContainer]}> <Animated.View style={styles.parentContainer}>
<KeyboardAvoidingView <KeyboardAvoidingView
style={{ style={{
width: '100%', width: '100%',
}} }}
behavior={Platform.OS === 'ios' ? 'padding' : null}> enabled={Platform.OS === 'ios'}
behavior="position">
<ScrollView <ScrollView
bounces={false} bounces={false}
ref={ref => (this.scrollViewRef = ref)} ref={this.scrollViewRef}
showsVerticalScrollIndicator={false} showsVerticalScrollIndicator={false}
onMomentumScrollBegin={this._onScrollBegin}
onMomentumScrollEnd={this._onScrollEnd}
scrollEnabled={scrollable} scrollEnabled={scrollable}
onScrollBeginDrag={this._onScrollBeginDrag} onScrollBeginDrag={this._onScrollBegin}
onScrollEndDrag={this._onScrollEndDrag} onScrollEndDrag={this._onScrollEnd}
onTouchEnd={this._onTouchEnd} onTouchEnd={this._onTouchEnd}
overScrollMode="always" //onScroll={this._onScroll}
style={[styles.scrollview]}> style={styles.scrollView}>
<Animated.View <Animated.View
onTouchStart={this._hideModal} onTouchStart={this._onTouchBackdrop}
onTouchEnd={this._hideModal} onTouchMove={this._onTouchBackdrop}
onTouchMove={this._hideModal} onTouchEnd={this._onTouchBackdrop}
style={{ style={{
height: '100%', height: '100%',
width: '100%', width: '100%',
@@ -270,7 +331,6 @@ export default class ActionSheet extends Component {
zIndex: 1, zIndex: 1,
}} }}
/> />
<View <View
onTouchMove={this._onTouchMove} onTouchMove={this._onTouchMove}
onTouchStart={this._onTouchStart} onTouchStart={this._onTouchStart}
@@ -278,7 +338,17 @@ export default class ActionSheet extends Component {
style={{ style={{
height: deviceHeight * 1.1, height: deviceHeight * 1.1,
width: '100%', width: '100%',
}}></View> zIndex: 10,
}}>
<TouchableOpacity
onPress={this._onTouchBackdrop}
onLongPress={this._onTouchBackdrop}
style={{
height: deviceHeight * 1.1,
width: '100%',
}}
/>
</View>
<Animated.View <Animated.View
onLayout={this._showModal} onLayout={this._showModal}
@@ -288,7 +358,7 @@ export default class ActionSheet extends Component {
{ {
...getElevation(elevation), ...getElevation(elevation),
zIndex: 11, zIndex: 11,
opacity: this.opacityValue,
transform: [ transform: [
{ {
translateY: this.transformValue, translateY: this.transformValue,
@@ -314,6 +384,7 @@ export default class ActionSheet extends Component {
style={[ style={[
{ {
width: '100%', width: '100%',
backgroundColor: 'transparent',
}, },
footerStyle, footerStyle,
{ {
@@ -338,7 +409,7 @@ ActionSheet.defaultProps = {
footerAlwaysVisible: false, footerAlwaysVisible: false,
headerAlwaysVisible: false, headerAlwaysVisible: false,
containerStyle: {}, containerStyle: {},
footerHeight: 80, footerHeight: 40,
footerStyle: {}, footerStyle: {},
animated: true, animated: true,
closeOnPressBack: true, closeOnPressBack: true,
@@ -347,13 +418,14 @@ ActionSheet.defaultProps = {
bounciness: 8, bounciness: 8,
extraScroll: 0, extraScroll: 0,
closeAnimationDuration: 300, closeAnimationDuration: 300,
openAnimationDuration: 200, openAnimationSpeed: 12,
springOffset: 50, springOffset: 50,
elevation: 5, elevation: 5,
initialOffsetFromBottom: 1, initialOffsetFromBottom: 1,
indicatorColor: 'gray', indicatorColor: 'gray',
defaultOverlayOpacity: 0.3, defaultOverlayOpacity: 0.3,
overlayColor: 'black', overlayColor: 'black',
closeOnTouchBackdrop: true,
onClose: () => {}, onClose: () => {},
onOpen: () => {}, onOpen: () => {},
}; };
@@ -370,12 +442,13 @@ ActionSheet.propTypes = {
animated: PropTypes.bool, animated: PropTypes.bool,
closeOnPressBack: PropTypes.bool, closeOnPressBack: PropTypes.bool,
gestureEnabled: PropTypes.bool, gestureEnabled: PropTypes.bool,
closeOnTouchBackdrop: PropTypes.bool,
bounceOnOpen: PropTypes.bool, bounceOnOpen: PropTypes.bool,
bounciness: PropTypes.number, bounciness: PropTypes.number,
springOffset: PropTypes.number, springOffset: PropTypes.number,
defaultOverlayOpacity: PropTypes.number, defaultOverlayOpacity: PropTypes.number,
closeAnimationDuration: PropTypes.number, closeAnimationDuration: PropTypes.number,
openAnimationDuration: PropTypes.number, openAnimationSpeed: PropTypes.number,
elevation: PropTypes.number, elevation: PropTypes.number,
initialOffsetFromBottom: PropTypes.number, initialOffsetFromBottom: PropTypes.number,
indicatorColor: PropTypes.string, indicatorColor: PropTypes.string,

View File

@@ -1,4 +1,5 @@
import {dialogActions} from './dialogActions'; import {dialogActions} from './dialogActions';
import {timeConverter} from '../../utils/utils';
export const TEMPLATE_DELETE = type => { export const TEMPLATE_DELETE = type => {
return { return {

View File

@@ -608,14 +608,13 @@ export const Menu = ({
width: '100%', width: '100%',
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
backgroundColor: colors.shade, justifyContent: noTextMode ? 'center' : 'flex-start',
backgroundColor: noTextMode ? 'transparent' : colors.shade,
paddingHorizontal: 12, paddingHorizontal: noTextMode ? 0 : 12,
}}> }}>
<View <View
style={{ style={{
width: 30, width: 30,
backgroundColor: colors.accent, backgroundColor: colors.accent,
height: 30, height: 30,
borderRadius: 100, borderRadius: 100,
@@ -632,6 +631,7 @@ export const Menu = ({
size={SIZE.md} size={SIZE.md}
/> />
</View> </View>
{noTextMode ? null : (
<View <View
style={{ style={{
marginLeft: 10, marginLeft: 10,
@@ -652,6 +652,7 @@ export const Menu = ({
Login to sync notes. Login to sync notes.
</Text> </Text>
</View> </View>
)}
</TouchableOpacity> </TouchableOpacity>
)} )}
</View> </View>

View File

@@ -47,7 +47,7 @@ var title = null;
let timer = null; let timer = null;
let saveCounter = 0; let saveCounter = 0;
let tapCount = 0; let tapCount = 0;
let canSave = false; let canSave = true;
const Editor = ({noMenu}) => { const Editor = ({noMenu}) => {
// Global State // Global State
const [state, dispatch] = useTracked(); const [state, dispatch] = useTracked();
@@ -77,7 +77,7 @@ const Editor = ({noMenu}) => {
}, []); }, []);
const loadNote = async item => { const loadNote = async item => {
EditorWebView.current?.requestFocus(); //EditorWebView.current?.requestFocus();
noMenu ? null : sideMenuRef.current?.setGestureEnabled(false); noMenu ? null : sideMenuRef.current?.setGestureEnabled(false);
if (note && note.id) { if (note && note.id) {
dispatch({type: ACTIONS.NOTES}); dispatch({type: ACTIONS.NOTES});
@@ -89,6 +89,7 @@ const Editor = ({noMenu}) => {
canSave = true; canSave = true;
} else { } else {
note = item; note = item;
canSave = false;
dispatch({ dispatch({
type: ACTIONS.CURRENT_EDITING_NOTE, type: ACTIONS.CURRENT_EDITING_NOTE,
id: item.id, id: item.id,
@@ -105,6 +106,7 @@ const Editor = ({noMenu}) => {
canSave = true; canSave = true;
} else { } else {
note = item; note = item;
canSave = false;
dispatch({ dispatch({
type: ACTIONS.CURRENT_EDITING_NOTE, type: ACTIONS.CURRENT_EDITING_NOTE,
id: item.id, id: item.id,
@@ -168,6 +170,7 @@ const Editor = ({noMenu}) => {
const onChange = data => { const onChange = data => {
if (data !== '') { if (data !== '') {
let rawData = JSON.parse(data); let rawData = JSON.parse(data);
if (rawData.type === 'content') { if (rawData.type === 'content') {
content = rawData; content = rawData;
} else { } else {
@@ -185,6 +188,7 @@ const Editor = ({noMenu}) => {
clearTimeout(timer); clearTimeout(timer);
timer = null; timer = null;
onChange(evt.nativeEvent.data); onChange(evt.nativeEvent.data);
timer = setTimeout(() => { timer = setTimeout(() => {
saveNote.call(this, true); saveNote.call(this, true);
}, 500); }, 500);
@@ -202,13 +206,15 @@ const Editor = ({noMenu}) => {
const saveNote = async (lockNote = true) => { const saveNote = async (lockNote = true) => {
if (!canSave) return; if (!canSave) return;
if (!title && !content) return; if (!title && !content) return;
if (!title && content && content.text.length <= 2) return;
if (!title && content && !content.text) return;
if ( if (
title && title &&
title.trim().length === 0 && title.trim().length <= 1 &&
content && content &&
content.text.length === 0 content.text &&
content.text.length <= 2
) )
return; return;
@@ -616,6 +622,17 @@ const Editor = ({noMenu}) => {
}}> }}>
{timeConverter(dateEdited)} {timeConverter(dateEdited)}
</Text> </Text>
<Text
style={{
color: colors.icon,
fontSize: SIZE.xxs,
textAlignVertical: 'center',
fontFamily: WEIGHT.regular,
marginLeft: 10,
}}>
{dateEdited ? 'Saved' : ''}
</Text>
</View> </View>
<WebView <WebView
ref={EditorWebView} ref={EditorWebView}