ui optimization for tablet

This commit is contained in:
ammarahm-ed
2020-01-22 02:51:24 +05:00
parent d5cf0b2a94
commit e654c97ab9
12 changed files with 408 additions and 219 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@@ -1,4 +1,4 @@
import React, {useState} from 'react'; import React, {useState, useEffect} from 'react';
import { import {
ActivityIndicator, ActivityIndicator,
FlatList, FlatList,
@@ -21,36 +21,44 @@ import {
SIZE, SIZE,
WEIGHT, WEIGHT,
} from '../../common/common'; } from '../../common/common';
import {useTracked} from '../../provider'; import {useTracked, ACTIONS} from '../../provider';
import {AnimatedSafeAreaView} from '../../views/Home'; import {AnimatedSafeAreaView} from '../../views/Home';
import {VaultDialog} from '../VaultDialog'; import {VaultDialog} from '../VaultDialog';
import {db} from '../../../App';
import {w} from '../../utils/utils';
let tagsInputRef; let tagsInputRef;
let tagsList; let tagsList;
export const EditorMenu = ({ export const EditorMenu = ({updateProps = () => {}, timestamp}) => {
close = () => {},
hide,
update = () => {},
updateProps = () => {},
noteProps,
note,
timestamp,
}) => {
const [state, dispatch] = useTracked(); const [state, dispatch] = useTracked();
const {colors} = state; const {colors} = state;
// Todo const [noteProps, setNoteProps] = useState({
pinned: false,
const changeColorScheme = () => {}; locked: false,
/////// favorite: false,
tags: [],
const [unlock, setUnlock] = useState(false); colors: [],
const [vaultDialog, setVaultDialog] = useState(false); });
const [focused, setFocused] = useState(false); const [focused, setFocused] = useState(false);
let tagToAdd = null; let tagToAdd = null;
let backPressCount = 0; let backPressCount = 0;
_renderListItem = ({item, index}) => ( function changeColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
let newColors = setColorScheme(colors, accent);
StatusBar.setBarStyle(newColors.night ? 'light-content' : 'dark-content');
dispatch({type: ACTIONS.THEME, colors: newColors});
}
useEffect(() => {
if (timestamp) {
setNoteProps({...db.getNote(timestamp)});
}
}, [timestamp]);
const _renderListItem = item => (
<TouchableOpacity <TouchableOpacity
key={item.name}
activeOpacity={opacity} activeOpacity={opacity}
onPress={() => { onPress={() => {
item.func(); item.func();
@@ -61,9 +69,7 @@ export const EditorMenu = ({
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'flex-end', alignItems: 'flex-end',
paddingHorizontal: 12, paddingVertical: pv,
paddingVertical: pv + 5,
paddingTop: index === 0 ? 5 : pv + 5,
}}> }}>
<View <View
style={{ style={{
@@ -76,12 +82,12 @@ export const EditorMenu = ({
}} }}
name={item.icon} name={item.icon}
color={colors.pri} color={colors.pri}
size={SIZE.md} size={SIZE.sm}
/> />
<Text <Text
style={{ style={{
fontFamily: WEIGHT.regular, fontFamily: WEIGHT.regular,
fontSize: SIZE.sm, fontSize: SIZE.sm - 1,
color: colors.pri, color: colors.pri,
}}> }}>
{item.name} {item.name}
@@ -89,7 +95,7 @@ export const EditorMenu = ({
</View> </View>
{item.switch ? ( {item.switch ? (
<Icon <Icon
size={SIZE.lg + 2} size={SIZE.lg}
color={item.on ? colors.accent : colors.icon} color={item.on ? colors.accent : colors.icon}
name={item.on ? 'toggle-right' : 'toggle-left'} name={item.on ? 'toggle-right' : 'toggle-left'}
/> />
@@ -101,8 +107,8 @@ export const EditorMenu = ({
style={{ style={{
borderWidth: 2, borderWidth: 2,
borderColor: item.on ? colors.accent : colors.icon, borderColor: item.on ? colors.accent : colors.icon,
width: 23, width: 22,
height: 23, height: 22,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
borderRadius: 100, borderRadius: 100,
@@ -116,29 +122,54 @@ export const EditorMenu = ({
</TouchableOpacity> </TouchableOpacity>
); );
_renderTag = item => ( _renderTag = tag => (
<TouchableOpacity <TouchableOpacity
key={tag}
onPress={() => {
let oldProps = {...noteProps};
oldProps.tags.splice(oldProps.tags.indexOf(tag), 1);
db.addNote({
dateCreated: timestamp,
content: noteProps.content,
title: noteProps.title,
tags: oldProps.tags,
});
localRefresh();
}}
style={{ style={{
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
margin: 5, margin: 1,
paddingHorizontal: 5, paddingHorizontal: 5,
paddingVertical: 2.5, paddingVertical: 2.5,
backgroundColor: colors.accent,
borderRadius: 5,
}}> }}>
<Text <Text
style={{ style={{
fontFamily: WEIGHT.regular, fontFamily: WEIGHT.regular,
fontSize: SIZE.sm - 2, fontSize: SIZE.sm,
color: 'white', color: colors.pri,
}}> }}>
{item} <Text
style={{
color: colors.accent,
}}>
{tag.slice(0, 1)}
</Text>
{tag.slice(1)}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
); );
const localRefresh = () => {
if (!timestamp) return;
let toAdd = db.getNote(timestamp);
setNoteProps({...toAdd});
};
_renderColor = item => ( _renderColor = item => (
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
@@ -149,25 +180,20 @@ export const EditorMenu = ({
props.colors.push(item); props.colors.push(item);
} }
updateProps(props); localRefresh();
}} }}
style={{ style={{
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'flex-start', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
marginRight: 5,
marginBottom: 5, marginBottom: 5,
borderWidth: 1.5,
borderRadius: 100, borderRadius: 100,
padding: 3,
borderColor: noteProps.colors.includes(item)
? colors.pri
: colors.shade,
}}> }}>
<View <View
style={{ style={{
width: 40, width: (w * 0.3) / 8.5,
height: 40, height: (w * 0.3) / 8.5,
backgroundColor: item, backgroundColor: item,
borderRadius: 100, borderRadius: 100,
justifyContent: 'center', justifyContent: 'center',
@@ -180,7 +206,7 @@ export const EditorMenu = ({
</TouchableOpacity> </TouchableOpacity>
); );
_onSubmit = () => { const _onSubmit = () => {
if (!tagToAdd || tagToAdd === '#') return; if (!tagToAdd || tagToAdd === '#') return;
let tag = tagToAdd; let tag = tagToAdd;
@@ -190,19 +216,31 @@ export const EditorMenu = ({
if (tag.includes(' ')) { if (tag.includes(' ')) {
tag = tag.replace(' ', '_'); tag = tag.replace(' ', '_');
} }
let oldProps = {...noteProps}; let oldProps = {...note};
oldProps.tags.push(tag);
if (oldProps.tags.includes(tag)) {
return;
} else {
oldProps.tags.push(tag);
}
tagsInputRef.setNativeProps({ tagsInputRef.setNativeProps({
text: '#', text: '#',
}); });
updateProps(oldProps); db.addNote({
dateCreated: timestamp,
content: noteProps.content,
title: noteProps.title,
tags: oldProps.tags,
});
localRefresh();
tagToAdd = ''; tagToAdd = '';
setTimeout(() => { setTimeout(() => {
tagsInputRef.focus(); //tagsInputRef.focus();
}, 300); }, 300);
}; };
_onKeyPress = event => { const _onKeyPress = event => {
if (event.nativeEvent.key === 'Backspace') { if (event.nativeEvent.key === 'Backspace') {
if (backPressCount === 0 && !tagToAdd) { if (backPressCount === 0 && !tagToAdd) {
backPressCount = 1; backPressCount = 1;
@@ -212,13 +250,20 @@ export const EditorMenu = ({
if (backPressCount === 1 && !tagToAdd) { if (backPressCount === 1 && !tagToAdd) {
backPressCount = 0; backPressCount = 0;
let tagInputValue = noteProps.tags[noteProps.tags.length - 1]; let tagInputValue = note.tags[note.tags.length - 1];
let oldProps = {...noteProps}; let oldProps = {...note};
if (allTags.length === 1) return; if (oldProps.tags.length === 1) return;
oldProps.tags.splice(allTags.length - 1); oldProps.tags.splice(oldProps.tags.length - 1);
db.addNote({
dateCreated: note.dateCreated,
content: note.content,
title: note.title,
tags: oldProps.tags,
});
localRefresh();
updateProps(oldProps);
tagsInputRef.setNativeProps({ tagsInputRef.setNativeProps({
text: tagInputValue, text: tagInputValue,
}); });
@@ -236,11 +281,11 @@ export const EditorMenu = ({
duration={300} duration={300}
style={{ style={{
height: '100%', height: '100%',
opacity: hide ? 0 : 1, opacity: 1,
backgroundColor: colors.shade, backgroundColor: colors.shade,
}}> }}>
<KeyboardAvoidingView <KeyboardAvoidingView
style={{height: '100%'}} style={{height: '100%', paddingHorizontal: 12, width: '100%'}}
behavior={Platform.OS === 'ios' ? 'padding' : null}> behavior={Platform.OS === 'ios' ? 'padding' : null}>
<ScrollView <ScrollView
contentContainerStyle={{ contentContainerStyle={{
@@ -251,7 +296,6 @@ export const EditorMenu = ({
style={{ style={{
height: 0, height: 0,
width: '100%', width: '100%',
marginTop: Platform.OS == 'ios' ? 0 : StatusBar.currentHeight, marginTop: Platform.OS == 'ios' ? 0 : StatusBar.currentHeight,
}} }}
/> />
@@ -260,7 +304,7 @@ export const EditorMenu = ({
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
width: '95%', width: '100%',
alignSelf: 'center', alignSelf: 'center',
height: 50, height: 50,
}}> }}>
@@ -274,8 +318,8 @@ export const EditorMenu = ({
</Text> </Text>
</View> </View>
<FlatList <View>
data={[ {[
{ {
name: 'Dark Mode', name: 'Dark Mode',
icon: 'moon', icon: 'moon',
@@ -302,10 +346,10 @@ export const EditorMenu = ({
name: 'Pinned', name: 'Pinned',
icon: 'tag', icon: 'tag',
func: () => { func: () => {
let props = {...noteProps}; if (!timestamp) return;
props.pinned = !noteProps.pinned; db.pinItem(note.type, note.dateCreated);
localRefresh();
updateProps(props); dispatch({type: ACTIONS.PINNED});
}, },
close: false, close: false,
check: true, check: true,
@@ -316,10 +360,11 @@ export const EditorMenu = ({
name: 'Add to Favorites', name: 'Add to Favorites',
icon: 'star', icon: 'star',
func: () => { func: () => {
let props = {...noteProps}; if (!timestamp) return;
props.favorite = !noteProps.favorite;
updateProps(props); db.favoriteItem(note.type, note.dateCreated);
localRefresh(item.type);
dispatch({type: ACTIONS.FAVORITES});
}, },
close: false, close: false,
check: true, check: true,
@@ -355,20 +400,17 @@ export const EditorMenu = ({
icon: 'lock', icon: 'lock',
func: () => { func: () => {
if (noteProps.locked) { if (noteProps.locked) {
setUnlock(true); //setUnlock(true);
} else { } else {
setUnlock(false); // setUnlock(false);
} }
setVaultDialog(true);
}, },
close: true, close: true,
check: true, check: true,
on: noteProps.locked, on: noteProps.locked,
}, },
]} ].map(_renderListItem)}
keyExtractor={(item, index) => item.name} </View>
renderItem={_renderListItem}
/>
<TouchableOpacity <TouchableOpacity
style={{ style={{
@@ -377,7 +419,6 @@ export const EditorMenu = ({
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'flex-end', alignItems: 'flex-end',
paddingHorizontal: 12,
marginTop: 15, marginTop: 15,
}}> }}>
<View <View
@@ -405,20 +446,21 @@ export const EditorMenu = ({
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<ScrollView <View
ref={ref => (tagsList = ref)} style={{
contentContainerStyle={{
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'wrap', flexWrap: 'wrap',
marginHorizontal: '5%',
marginBottom: 0, marginBottom: 0,
marginTop: 10, marginTop: 10,
borderRadius: 5, borderRadius: 5,
backgroundColor: colors.nav,
borderWidth: 1.5, borderWidth: 1.5,
borderColor: focused ? colors.accent : 'transparent', borderColor: focused ? colors.accent : colors.nav,
paddingVertical: 5,
backgroundColor: colors.nav,
}}> }}>
{noteProps.tags.map(_renderTag)} {noteProps && noteProps.tags
? noteProps.tags.map(_renderTag)
: null}
<TextInput <TextInput
style={{ style={{
backgroundColor: 'transparent', backgroundColor: 'transparent',
@@ -426,16 +468,16 @@ export const EditorMenu = ({
fontFamily: WEIGHT.regular, fontFamily: WEIGHT.regular,
color: colors.pri, color: colors.pri,
paddingHorizontal: 5, paddingHorizontal: 5,
paddingVertical: 2.5, paddingVertical: 1.5,
margin: 5, margin: 1,
}} }}
blurOnSubmit={false}
ref={ref => (tagsInputRef = ref)} ref={ref => (tagsInputRef = ref)}
placeholderTextColor={colors.icon} placeholderTextColor={colors.icon}
onFocus={() => { onFocus={() => {
setFocused(true); setFocused(true);
}} }}
selectionColor={colors.accent} selectionColor={colors.accent}
selectTextOnFocus={true}
onBlur={() => { onBlur={() => {
setFocused(false); setFocused(false);
}} }}
@@ -444,10 +486,10 @@ export const EditorMenu = ({
tagToAdd = value; tagToAdd = value;
if (tagToAdd.length > 0) backPressCount = 0; if (tagToAdd.length > 0) backPressCount = 0;
}} }}
onKeyPress={_onKeyPress}
onSubmitEditing={_onSubmit} onSubmitEditing={_onSubmit}
onKeyPress={_onKeyPress}
/> />
</ScrollView> </View>
<TouchableOpacity <TouchableOpacity
style={{ style={{
@@ -456,7 +498,6 @@ export const EditorMenu = ({
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'flex-end', alignItems: 'flex-end',
paddingHorizontal: 12,
marginTop: 15, marginTop: 15,
}}> }}>
<View <View
@@ -484,13 +525,14 @@ export const EditorMenu = ({
</View> </View>
</TouchableOpacity> </TouchableOpacity>
<ScrollView <View
contentContainerStyle={{ style={{
flexDirection: 'row', flexDirection: 'row',
flexWrap: 'wrap', flexWrap: 'wrap',
paddingHorizontal: '5%',
marginBottom: 15, marginBottom: 15,
marginTop: 10, marginTop: 10,
width: '100%',
justifyContent: 'space-between',
}}> }}>
{[ {[
'red', 'red',
@@ -501,7 +543,7 @@ export const EditorMenu = ({
'orange', 'orange',
'gray', 'gray',
].map(_renderColor)} ].map(_renderColor)}
</ScrollView> </View>
</View> </View>
</ScrollView> </ScrollView>
@@ -524,24 +566,6 @@ export const EditorMenu = ({
{} {}
<ActivityIndicator color={colors.accent} /> <ActivityIndicator color={colors.accent} />
</View> </View>
<VaultDialog
close={(item, locked) => {
if (item) {
update(item);
}
let props = {...noteProps};
props.locked = locked;
updateProps(props);
setVaultDialog(false);
setUnlock(false);
}}
note={note}
timestamp={timestamp}
perm={true}
openedToUnlock={unlock}
visible={vaultDialog}
/>
</KeyboardAvoidingView> </KeyboardAvoidingView>
</AnimatedSafeAreaView> </AnimatedSafeAreaView>
); );

View File

@@ -1,5 +1,11 @@
import React from 'react'; import React from 'react';
import {Dimensions, Text, TouchableOpacity, View} from 'react-native'; import {
Dimensions,
Text,
TouchableOpacity,
View,
DeviceEventEmitter,
} from 'react-native';
import Icon from 'react-native-vector-icons/Feather'; import Icon from 'react-native-vector-icons/Feather';
import {DDS} from '../../../App'; import {DDS} from '../../../App';
import {ph, pv, SIZE, WEIGHT} from '../../common/common'; import {ph, pv, SIZE, WEIGHT} from '../../common/common';
@@ -48,12 +54,10 @@ export default class NoteItem extends React.Component {
let { let {
colors, colors,
item, item,
width,
customStyle, customStyle,
onLongPress, onLongPress,
isTrash, isTrash,
pinned, pinned,
update,
index, index,
} = this.props; } = this.props;
console.log('rendering', index); console.log('rendering', index);
@@ -65,9 +69,7 @@ export default class NoteItem extends React.Component {
justifyContent: 'flex-start', justifyContent: 'flex-start',
alignItems: 'center', alignItems: 'center',
flexDirection: 'row', flexDirection: 'row',
marginHorizontal: 12, maxWidth: '100%',
width: width,
paddingRight: 6, paddingRight: 6,
alignSelf: 'center', alignSelf: 'center',
borderBottomWidth: 1, borderBottomWidth: 1,
@@ -110,9 +112,11 @@ export default class NoteItem extends React.Component {
vaultDialog: true, vaultDialog: true,
}); });
} else { } else {
NavigationService.navigate('Editor', { DDS.isTab
note: item, ? DeviceEventEmitter.emit('loadNoteEvent', item)
}); : NavigationService.navigate('Editor', {
note: item,
});
} }
}} }}
style={{ style={{

View File

@@ -8,6 +8,7 @@ import {NotesPlaceHolder} from '../ListPlaceholders';
import NoteItem from '../NoteItem'; import NoteItem from '../NoteItem';
import SelectionWrapper from '../SelectionWrapper'; import SelectionWrapper from '../SelectionWrapper';
import PullToRefresh from '../PullToRefresh'; import PullToRefresh from '../PullToRefresh';
import {DDS} from '../../../App';
let sectionListRef; let sectionListRef;
export const NotesList = ({ export const NotesList = ({
onScroll, onScroll,
@@ -25,7 +26,7 @@ export const NotesList = ({
<NoteItem <NoteItem
colors={colors} colors={colors}
customStyle={{ customStyle={{
width: selectionMode ? w - 74 : '100%', width: selectionMode ? '90%' : '100%',
marginHorizontal: 0, marginHorizontal: 0,
}} }}
onLongPress={() => { onLongPress={() => {

View File

@@ -22,6 +22,7 @@ export const Search = props => {
height: 60, height: 60,
justifyContent: 'center', justifyContent: 'center',
marginTop: props.hide ? -65 : 0, marginTop: props.hide ? -65 : 0,
paddingHorizontal: 12,
}}> }}>
<Animatable.View <Animatable.View
transition={['borderWidth']} transition={['borderWidth']}
@@ -31,7 +32,7 @@ export const Search = props => {
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
paddingLeft: 12, paddingLeft: 12,
width: w - 24, width: '100%',
alignSelf: 'center', alignSelf: 'center',
borderRadius: br, borderRadius: br,
height: '90%', height: '90%',

View File

@@ -31,17 +31,21 @@ export const SelectionHeader = ({navigation}) => {
style={{ style={{
width: '100%', width: '100%',
position: 'absolute', position: 'absolute',
height: selectionMode ? 50 + StatusBar.currentHeight : 0, height: selectionMode
? Platform.OS === 'android'
? 50 + StatusBar.currentHeight
: 50
: 0,
opacity: selectionMode ? 1 : 0, opacity: selectionMode ? 1 : 0,
backgroundColor: colors.bg, backgroundColor: colors.bg,
paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight, paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
justifyContent: 'flex-end', justifyContent: 'flex-end',
zIndex: 11, zIndex: 11,
paddingHorizontal: 12,
}}> }}>
<View <View
style={{ style={{
width: w - 24, width: '100%',
marginHorizontal: 12,
height: 50, height: 50,
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',

View File

@@ -15,21 +15,21 @@ const SelectionWrapper = ({children, item}) => {
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
width: w - 24, width: '100%',
paddingHorizontal: 12,
marginHorizontal: 12,
}}> }}>
<TouchableOpacity <View
onPress={() => { onPress={() => {
dispatch({type: ACTIONS.SELECTED_ITEMS, item: item}); dispatch({type: ACTIONS.SELECTED_ITEMS, item: item});
}} }}
style={{ style={{
width: 50, width: '10%',
height: 70, height: 70,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'flex-start', alignItems: 'center',
display: selectionMode ? 'flex' : 'none', display: selectionMode ? 'flex' : 'none',
opacity: selectionMode ? 1 : 0, opacity: selectionMode ? 1 : 0,
paddingRight: 10,
}}> }}>
<View <View
style={{ style={{
@@ -48,7 +48,7 @@ const SelectionWrapper = ({children, item}) => {
<Icon size={SIZE.md} color={colors.accent} name="check" /> <Icon size={SIZE.md} color={colors.accent} name="check" />
) : null} ) : null}
</View> </View>
</TouchableOpacity> </View>
{children} {children}
</View> </View>

View File

@@ -7,6 +7,7 @@ import {useTracked} from '../../provider';
import NavigationService from '../../services/NavigationService'; import NavigationService from '../../services/NavigationService';
import {SideMenuEvent} from '../../utils/utils'; import {SideMenuEvent} from '../../utils/utils';
import {moveNoteHideEvent} from '../DialogManager'; import {moveNoteHideEvent} from '../DialogManager';
import {DDS} from '../../../App';
let isOpen = false; let isOpen = false;
export const Header = ({ export const Header = ({
heading, heading,
@@ -81,7 +82,7 @@ export const Header = ({
) : ( ) : (
undefined undefined
)} )}
{menu ? ( {menu && !DDS.isTab ? (
<TouchableOpacity <TouchableOpacity
hitSlop={{top: 20, bottom: 20, left: 50, right: 40}} hitSlop={{top: 20, bottom: 20, left: 50, right: 40}}
onPress={() => { onPress={() => {

View File

@@ -1,13 +1,14 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import { import {
BackHandler, BackHandler,
Dimensions,
KeyboardAvoidingView, KeyboardAvoidingView,
Linking, Linking,
Platform, Platform,
StatusBar, StatusBar,
TouchableOpacity, TouchableOpacity,
View, View,
DeviceEventEmitter,
ActivityIndicator,
} from 'react-native'; } from 'react-native';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import Icon from 'react-native-vector-icons/Feather'; import Icon from 'react-native-vector-icons/Feather';
@@ -18,29 +19,77 @@ import {
ActionSheetEvent, ActionSheetEvent,
simpleDialogEvent, simpleDialogEvent,
TEMPLATE_EXIT, TEMPLATE_EXIT,
_recieveEvent,
_unSubscribeEvent,
TEMPLATE_EXIT_FULLSCREEN,
} from '../../components/DialogManager'; } from '../../components/DialogManager';
import {EditorMenu} from '../../components/EditorMenu';
import {useTracked, ACTIONS} from '../../provider'; import {useTracked, ACTIONS} from '../../provider';
import {SideMenuEvent} from '../../utils/utils'; import {SideMenuEvent, w} from '../../utils/utils';
import {AnimatedSafeAreaView} from '../Home'; import {AnimatedSafeAreaView} from '../Home';
let EditorWebView; let EditorWebView;
let note = {}; let note = {};
var timestamp = null; let timestamp = null;
var content = null; var content = null;
var title = null; var title = null;
let timer = null; let timer = null;
const Editor = ({navigation}) => { let saveCounter = 0;
const Editor = ({navigation, noMenu}) => {
// Global State // Global State
const [state, dispatch] = useTracked(); const [state, dispatch] = useTracked();
const {colors} = state; const {colors} = state;
const [loading, setLoading] = useState(false);
// Local State let fullscreen = false;
const [sidebar, setSidebar] = useState(DDS.isTab ? true : false);
// FUNCTIONS // FUNCTIONS
const post = value => EditorWebView.postMessage(value); const post = value => EditorWebView.postMessage(value);
useEffect(() => {
_recieveEvent('loadNoteEvent', loadNote);
return () => {
_unSubscribeEvent('loadNoteEvent', loadNote);
};
}, []);
const loadNote = item => {
if (note && note.dateCreated) {
saveNote(true).then(() => {
dispatch({type: ACTIONS.NOTES});
if (item && item.type === 'new') {
clearEditor();
} else {
note = item;
updateEditor();
}
});
} else {
dispatch({type: ACTIONS.NOTES});
if (item && item.type === 'new') {
clearEditor();
} else {
note = item;
updateEditor();
}
}
};
const clearEditor = () => {
timestamp = null;
title = null;
content = null;
note = {};
saveCounter = 0;
post('{}');
post(
JSON.stringify({
type: 'title',
value: null,
}),
);
};
const onChange = data => { const onChange = data => {
if (data !== '') { if (data !== '') {
@@ -59,7 +108,7 @@ const Editor = ({navigation}) => {
timer = null; timer = null;
onChange(evt.nativeEvent.data); onChange(evt.nativeEvent.data);
timer = setTimeout(() => { timer = setTimeout(() => {
saveNote(true); saveNote.call(this, true);
}, 1000); }, 1000);
} }
}; };
@@ -73,7 +122,10 @@ const Editor = ({navigation}) => {
} }
}; };
const saveNote = async (noteProps = {}, lockNote = true) => { const saveNote = async (lockNote = true) => {
if (!title && !content) return;
if (title === '' && content.text === '') return;
if (!content) { if (!content) {
content = { content = {
text: '', text: '',
@@ -81,7 +133,7 @@ const Editor = ({navigation}) => {
}; };
} }
timestamp = await db.addNote({ let dateCreated = await db.addNote({
title, title,
content: { content: {
text: content.text, text: content.text,
@@ -89,21 +141,60 @@ const Editor = ({navigation}) => {
}, },
dateCreated: timestamp, dateCreated: timestamp,
}); });
if (timestamp !== dateCreated) {
timestamp = dateCreated;
}
if (lockNote && db.getNote(timestamp).locked) { if (content.text.length < 200 || saveCounter < 2) {
db.lockNote(timestamp, 'password'); dispatch({
type: ACTIONS.NOTES,
});
}
saveCounter++;
if (timestamp) {
let lockednote = db.getNote(timestamp);
if (lockNote && lockednote.locked) {
await db.lockNote(timestamp, 'password');
}
} }
}; };
const onWebViewLoad = () => { const onWebViewLoad = () => {
post(JSON.stringify(colors)); if (noMenu) {
if (navigation.state.params && navigation.state.params.note) { post(
JSON.stringify({
type: 'nomenu',
value: true,
}),
);
} else {
post(
JSON.stringify({
type: 'nomenu',
value: false,
}),
);
}
if (navigation && navigation.state.params && navigation.state.params.note) {
note = navigation.state.params.note; note = navigation.state.params.note;
updateEditor(); updateEditor();
} else if (note && note.dateCreated) {
updateEditor();
} }
post(JSON.stringify(colors));
setTimeout(() => {
setLoading(false);
}, 1000);
}; };
const updateEditor = () => { const updateEditor = () => {
title = note.title;
timestamp = note.dateCreated;
content = note.content;
saveCounter = 0;
post(JSON.stringify(note.content.delta)); post(JSON.stringify(note.content.delta));
post( post(
JSON.stringify({ JSON.stringify({
@@ -111,12 +202,10 @@ const Editor = ({navigation}) => {
value: note.title, value: note.title,
}), }),
); );
title = note.title;
timestamp = note.dateCreated;
content = note.content;
}; };
const params = 'platform=' + Platform.OS; const params = 'platform=' + Platform.OS;
const sourceUri = const sourceUri =
(Platform.OS === 'android' ? 'file:///android_asset/' : '') + (Platform.OS === 'android' ? 'file:///android_asset/' : '') +
'Web.bundle/loader.html'; 'Web.bundle/loader.html';
@@ -132,52 +221,100 @@ const Editor = ({navigation}) => {
behavior={Platform.OS === 'ios' ? 'padding' : null} behavior={Platform.OS === 'ios' ? 'padding' : null}
style={{ style={{
height: '100%', height: '100%',
width: '100%',
backgroundColor: 'transparent',
}}> }}>
<View <View
style={{ style={{
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight, marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
}} }}
/> />
<TouchableOpacity
onPress={() => { <Animatable.View
simpleDialogEvent(TEMPLATE_EXIT('Editor')); transition={['translateX', 'opacity']}
}} duration={300}
style={{ style={{
width: '12.5%', width: '100%',
height: 50, height: '100%',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'flex-start', alignItems: 'center',
position: 'absolute',
left: 0,
top: 0,
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
paddingLeft: 12,
zIndex: 999, zIndex: 999,
position: 'absolute',
backgroundColor: colors.bg,
opacity: loading ? 1 : 0,
transform: [
{
translateX: loading ? 0 : w * 1.5,
},
],
}}> }}>
<Icon {loading ? (
style={{ <ActivityIndicator color={colors.accent} size={SIZE.xxl} />
marginLeft: -7, ) : null}
</Animatable.View>
{noMenu ? null : (
<TouchableOpacity
onPress={() => {
simpleDialogEvent(TEMPLATE_EXIT('Editor'));
}} }}
name="chevron-left" style={{
color={colors.icon} width: 60,
size={SIZE.xxxl - 3} height: 50,
/> justifyContent: 'center',
</TouchableOpacity> alignItems: 'flex-start',
position: 'absolute',
left: 0,
top: 0,
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
paddingLeft: 12,
zIndex: 800,
}}>
<Icon
style={{
marginLeft: -7,
marginTop: -3.5,
}}
name="chevron-left"
color={colors.icon}
size={SIZE.xxxl - 3}
/>
</TouchableOpacity>
)}
<TouchableOpacity <TouchableOpacity
onPress={() => { onPress={() => {
DDS.isTab if (fullscreen) {
? setSidebar(!sidebar) DeviceEventEmitter.emit('closeFullScreenEditor');
: ActionSheetEvent( fullscreen = false;
note, post(
true, JSON.stringify({
true, type: 'nomenu',
['Add to', 'Share', 'Export', 'Delete'], value: true,
['Dark Mode', 'Add to Vault', 'Pin', 'Favorite'], }),
); );
} else {
DeviceEventEmitter.emit('showFullScreenEditor');
fullscreen = true;
post(
JSON.stringify({
type: 'nomenu',
value: false,
}),
);
}
return;
ActionSheetEvent(
note,
true,
true,
['Add to', 'Share', 'Export', 'Delete'],
['Dark Mode', 'Add to Vault', 'Pin', 'Favorite'],
);
}} }}
style={{ style={{
width: '12.5%', width: 60,
height: 50, height: 50,
justifyContent: 'center', justifyContent: 'center',
alignItems: 'flex-end', alignItems: 'flex-end',
@@ -186,7 +323,7 @@ const Editor = ({navigation}) => {
top: 0, top: 0,
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight, marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
paddingRight: 12, paddingRight: 12,
zIndex: 999, zIndex: 800,
}}> }}>
<Icon name="more-horizontal" color={colors.icon} size={SIZE.xxxl} /> <Icon name="more-horizontal" color={colors.icon} size={SIZE.xxxl} />
</TouchableOpacity> </TouchableOpacity>
@@ -196,7 +333,8 @@ const Editor = ({navigation}) => {
onError={error => console.log(error)} onError={error => console.log(error)}
onLoad={onWebViewLoad} onLoad={onWebViewLoad}
javaScriptEnabled javaScriptEnabled
onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest} injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null}
//onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest}
renderLoading={() => ( renderLoading={() => (
<View <View
style={{ style={{
@@ -206,22 +344,19 @@ const Editor = ({navigation}) => {
}} }}
/> />
)} )}
cacheEnabled={true} cacheMode="LOAD_NO_CACHE"
cacheEnabled={false}
domStorageEnabled domStorageEnabled
scrollEnabled={false} scrollEnabled={false}
bounces={true} bounces={true}
allowFileAccess={true} allowFileAccess={true}
scalesPageToFit={true} scalesPageToFit={true}
allowFileAccessFromFileURLs={true}
allowUniversalAccessFromFileURLs={true}
originWhitelist={'*'} originWhitelist={'*'}
injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null} source={{
source={ uri: 'http://192.168.10.9:8080/texteditor.html',
Platform.OS === 'ios' }}
? {uri: sourceUri}
: {
uri: 'file:///android_asset/texteditor.html',
baseUrl: 'baseUrl:"file:///android_asset/',
}
}
style={{ style={{
height: '100%', height: '100%',
maxHeight: '100%', maxHeight: '100%',
@@ -236,24 +371,35 @@ const Editor = ({navigation}) => {
// EFFECTS // EFFECTS
useEffect(() => { useEffect(() => {
let handleBack = BackHandler.addEventListener('hardwareBackPress', () => { let handleBack;
simpleDialogEvent(TEMPLATE_EXIT('Editor')); if (!noMenu) {
handleBack = BackHandler.addEventListener('hardwareBackPress', () => {
simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN());
return true;
});
} else {
if (handleBack) {
handleBack.remove();
handleBack = null;
}
}
return true;
});
return () => { return () => {
handleBack.remove(); if (handleBack) {
handleBack = null; handleBack.remove();
handleBack = null;
}
title = null; title = null;
content = null; content = null;
timer = null; timer = null;
timestamp = null;
}; };
}, []); }, [noMenu]);
useEffect(() => { useEffect(() => {
SideMenuEvent.disable(); noMenu ? null : SideMenuEvent.disable();
return () => { return () => {
if (noMenu) return;
DDS.isTab ? SideMenuEvent.open() : null; DDS.isTab ? SideMenuEvent.open() : null;
SideMenuEvent.enable(); SideMenuEvent.enable();
}; };
@@ -271,18 +417,11 @@ const Editor = ({navigation}) => {
flex: 1, flex: 1,
backgroundColor: colors.bg, backgroundColor: colors.bg,
height: '100%', height: '100%',
width: sidebar ? '70%' : '100%', width: '100%',
flexDirection: 'row',
justifyContent: 'space-between',
}}> }}>
{_renderEditor()} {_renderEditor()}
<Animatable.View
transition={['width', 'opacity']}
duration={300}
style={{
width: sidebar ? '30%' : '0%',
opacity: sidebar ? 1 : 0,
}}>
{DDS.isTab ? <EditorMenu hide={false} /> : null}
</Animatable.View>
</AnimatedSafeAreaView> </AnimatedSafeAreaView>
); );
}; };

View File

@@ -15,6 +15,7 @@ import {ACTIONS, useTracked} from '../../provider';
import {slideLeft, slideRight} from '../../utils/animations'; import {slideLeft, slideRight} from '../../utils/animations';
import {w} from '../../utils/utils'; import {w} from '../../utils/utils';
import {AddNotebookEvent} from '../../components/DialogManager'; import {AddNotebookEvent} from '../../components/DialogManager';
import {DDS} from '../../../App';
export const Folders = ({navigation}) => { export const Folders = ({navigation}) => {
const [state, dispatch] = useTracked(); const [state, dispatch] = useTracked();
@@ -171,7 +172,7 @@ export const Folders = ({navigation}) => {
<View <View
style={{ style={{
height: '80%', height: '80%',
width: '100%', width: DDS.isTab ? '70%' : '100%',
alignItems: 'center', alignItems: 'center',
alignSelf: 'center', alignSelf: 'center',
justifyContent: 'center', justifyContent: 'center',
@@ -204,6 +205,7 @@ export const Folders = ({navigation}) => {
contentContainerStyle={{ contentContainerStyle={{
width: '100%', width: '100%',
alignSelf: 'center', alignSelf: 'center',
minHeight: '100%',
}} }}
ListFooterComponent={ ListFooterComponent={
<View <View

View File

@@ -1,7 +1,7 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {SafeAreaView, View} from 'react-native'; import {SafeAreaView, View, DeviceEventEmitter} from 'react-native';
import * as Animatable from 'react-native-animatable'; import * as Animatable from 'react-native-animatable';
import {db} from '../../../App'; import {db, DDS} from '../../../App';
import Container from '../../components/Container'; import Container from '../../components/Container';
import {Header} from '../../components/header'; import {Header} from '../../components/header';
import {NotesList} from '../../components/NotesList'; import {NotesList} from '../../components/NotesList';
@@ -12,6 +12,7 @@ import NavigationService from '../../services/NavigationService';
import {SideMenuEvent, ToastEvent} from '../../utils/utils'; import {SideMenuEvent, ToastEvent} from '../../utils/utils';
import {useIsFocused} from 'react-navigation-hooks'; import {useIsFocused} from 'react-navigation-hooks';
import PullToRefresh from '../../components/PullToRefresh'; import PullToRefresh from '../../components/PullToRefresh';
import Editor from '../Editor';
export const AnimatedSafeAreaView = Animatable.createAnimatableComponent( export const AnimatedSafeAreaView = Animatable.createAnimatableComponent(
SafeAreaView, SafeAreaView,
@@ -100,9 +101,14 @@ export const Home = ({navigation}) => {
bottomButtonText="Add a new note" bottomButtonText="Add a new note"
bottomButtonOnPress={() => { bottomButtonOnPress={() => {
dispatch({type: ACTIONS.NOTES}); dispatch({type: ACTIONS.NOTES});
SideMenuEvent.close();
SideMenuEvent.disable(); if (DDS.isTab) {
NavigationService.navigate('Editor'); DeviceEventEmitter.emit('loadNoteEvent', {type: 'new'});
} else {
SideMenuEvent.close();
SideMenuEvent.disable();
NavigationService.navigate('Editor');
}
}}> }}>
<SelectionHeader /> <SelectionHeader />
<Animatable.View <Animatable.View

View File

@@ -1,5 +1,11 @@
import React from 'react'; import React from 'react';
import {ScrollView, Text, TouchableOpacity, View} from 'react-native'; import {
ScrollView,
Text,
TouchableOpacity,
View,
StatusBar,
} from 'react-native';
import FastStorage from 'react-native-fast-storage'; import FastStorage from 'react-native-fast-storage';
import {FlatList} from 'react-native-gesture-handler'; import {FlatList} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/Feather'; import Icon from 'react-native-vector-icons/Feather';
@@ -12,10 +18,11 @@ import {
pv, pv,
SIZE, SIZE,
WEIGHT, WEIGHT,
setColorScheme,
} from '../../common/common'; } from '../../common/common';
import Container from '../../components/Container'; import Container from '../../components/Container';
import {Header} from '../../components/header'; import {Header} from '../../components/header';
import {useTracked} from '../../provider'; import {useTracked, ACTIONS} from '../../provider';
import NavigationService from '../../services/NavigationService'; import NavigationService from '../../services/NavigationService';
export const Settings = ({navigation}) => { export const Settings = ({navigation}) => {
const [state, dispatch] = useTracked(); const [state, dispatch] = useTracked();