mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-23 15:09:33 +01:00
ui optimization for tablet
This commit is contained in:
BIN
apps/mobile/android/app/src/main/assets/favicon.ico
Normal file
BIN
apps/mobile/android/app/src/main/assets/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 318 B |
@@ -1,4 +1,4 @@
|
||||
import React, {useState} from 'react';
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
FlatList,
|
||||
@@ -21,36 +21,44 @@ import {
|
||||
SIZE,
|
||||
WEIGHT,
|
||||
} from '../../common/common';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useTracked, ACTIONS} from '../../provider';
|
||||
import {AnimatedSafeAreaView} from '../../views/Home';
|
||||
import {VaultDialog} from '../VaultDialog';
|
||||
import {db} from '../../../App';
|
||||
import {w} from '../../utils/utils';
|
||||
|
||||
let tagsInputRef;
|
||||
let tagsList;
|
||||
export const EditorMenu = ({
|
||||
close = () => {},
|
||||
hide,
|
||||
update = () => {},
|
||||
updateProps = () => {},
|
||||
noteProps,
|
||||
note,
|
||||
timestamp,
|
||||
}) => {
|
||||
export const EditorMenu = ({updateProps = () => {}, timestamp}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
// Todo
|
||||
|
||||
const changeColorScheme = () => {};
|
||||
///////
|
||||
|
||||
const [unlock, setUnlock] = useState(false);
|
||||
const [vaultDialog, setVaultDialog] = useState(false);
|
||||
const [noteProps, setNoteProps] = useState({
|
||||
pinned: false,
|
||||
locked: false,
|
||||
favorite: false,
|
||||
tags: [],
|
||||
colors: [],
|
||||
});
|
||||
const [focused, setFocused] = useState(false);
|
||||
|
||||
let tagToAdd = null;
|
||||
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
|
||||
key={item.name}
|
||||
activeOpacity={opacity}
|
||||
onPress={() => {
|
||||
item.func();
|
||||
@@ -61,9 +69,7 @@ export const EditorMenu = ({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-end',
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: pv + 5,
|
||||
paddingTop: index === 0 ? 5 : pv + 5,
|
||||
paddingVertical: pv,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
@@ -76,12 +82,12 @@ export const EditorMenu = ({
|
||||
}}
|
||||
name={item.icon}
|
||||
color={colors.pri}
|
||||
size={SIZE.md}
|
||||
size={SIZE.sm}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: WEIGHT.regular,
|
||||
fontSize: SIZE.sm,
|
||||
fontSize: SIZE.sm - 1,
|
||||
color: colors.pri,
|
||||
}}>
|
||||
{item.name}
|
||||
@@ -89,7 +95,7 @@ export const EditorMenu = ({
|
||||
</View>
|
||||
{item.switch ? (
|
||||
<Icon
|
||||
size={SIZE.lg + 2}
|
||||
size={SIZE.lg}
|
||||
color={item.on ? colors.accent : colors.icon}
|
||||
name={item.on ? 'toggle-right' : 'toggle-left'}
|
||||
/>
|
||||
@@ -101,8 +107,8 @@ export const EditorMenu = ({
|
||||
style={{
|
||||
borderWidth: 2,
|
||||
borderColor: item.on ? colors.accent : colors.icon,
|
||||
width: 23,
|
||||
height: 23,
|
||||
width: 22,
|
||||
height: 22,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 100,
|
||||
@@ -116,29 +122,54 @@ export const EditorMenu = ({
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
_renderTag = item => (
|
||||
_renderTag = tag => (
|
||||
<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={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
margin: 5,
|
||||
margin: 1,
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 2.5,
|
||||
backgroundColor: colors.accent,
|
||||
borderRadius: 5,
|
||||
}}>
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: WEIGHT.regular,
|
||||
fontSize: SIZE.sm - 2,
|
||||
color: 'white',
|
||||
fontSize: SIZE.sm,
|
||||
color: colors.pri,
|
||||
}}>
|
||||
{item}
|
||||
<Text
|
||||
style={{
|
||||
color: colors.accent,
|
||||
}}>
|
||||
{tag.slice(0, 1)}
|
||||
</Text>
|
||||
{tag.slice(1)}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
const localRefresh = () => {
|
||||
if (!timestamp) return;
|
||||
|
||||
let toAdd = db.getNote(timestamp);
|
||||
|
||||
setNoteProps({...toAdd});
|
||||
};
|
||||
|
||||
_renderColor = item => (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
@@ -149,25 +180,20 @@ export const EditorMenu = ({
|
||||
props.colors.push(item);
|
||||
}
|
||||
|
||||
updateProps(props);
|
||||
localRefresh();
|
||||
}}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
marginRight: 5,
|
||||
|
||||
marginBottom: 5,
|
||||
borderWidth: 1.5,
|
||||
borderRadius: 100,
|
||||
padding: 3,
|
||||
borderColor: noteProps.colors.includes(item)
|
||||
? colors.pri
|
||||
: colors.shade,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
width: 40,
|
||||
height: 40,
|
||||
width: (w * 0.3) / 8.5,
|
||||
height: (w * 0.3) / 8.5,
|
||||
backgroundColor: item,
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
@@ -180,7 +206,7 @@ export const EditorMenu = ({
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
_onSubmit = () => {
|
||||
const _onSubmit = () => {
|
||||
if (!tagToAdd || tagToAdd === '#') return;
|
||||
|
||||
let tag = tagToAdd;
|
||||
@@ -190,19 +216,31 @@ export const EditorMenu = ({
|
||||
if (tag.includes(' ')) {
|
||||
tag = tag.replace(' ', '_');
|
||||
}
|
||||
let oldProps = {...noteProps};
|
||||
let oldProps = {...note};
|
||||
|
||||
if (oldProps.tags.includes(tag)) {
|
||||
return;
|
||||
} else {
|
||||
oldProps.tags.push(tag);
|
||||
}
|
||||
|
||||
tagsInputRef.setNativeProps({
|
||||
text: '#',
|
||||
});
|
||||
updateProps(oldProps);
|
||||
db.addNote({
|
||||
dateCreated: timestamp,
|
||||
content: noteProps.content,
|
||||
title: noteProps.title,
|
||||
tags: oldProps.tags,
|
||||
});
|
||||
localRefresh();
|
||||
tagToAdd = '';
|
||||
setTimeout(() => {
|
||||
tagsInputRef.focus();
|
||||
//tagsInputRef.focus();
|
||||
}, 300);
|
||||
};
|
||||
|
||||
_onKeyPress = event => {
|
||||
const _onKeyPress = event => {
|
||||
if (event.nativeEvent.key === 'Backspace') {
|
||||
if (backPressCount === 0 && !tagToAdd) {
|
||||
backPressCount = 1;
|
||||
@@ -212,13 +250,20 @@ export const EditorMenu = ({
|
||||
if (backPressCount === 1 && !tagToAdd) {
|
||||
backPressCount = 0;
|
||||
|
||||
let tagInputValue = noteProps.tags[noteProps.tags.length - 1];
|
||||
let oldProps = {...noteProps};
|
||||
if (allTags.length === 1) return;
|
||||
let tagInputValue = note.tags[note.tags.length - 1];
|
||||
let oldProps = {...note};
|
||||
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({
|
||||
text: tagInputValue,
|
||||
});
|
||||
@@ -236,11 +281,11 @@ export const EditorMenu = ({
|
||||
duration={300}
|
||||
style={{
|
||||
height: '100%',
|
||||
opacity: hide ? 0 : 1,
|
||||
opacity: 1,
|
||||
backgroundColor: colors.shade,
|
||||
}}>
|
||||
<KeyboardAvoidingView
|
||||
style={{height: '100%'}}
|
||||
style={{height: '100%', paddingHorizontal: 12, width: '100%'}}
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : null}>
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
@@ -251,7 +296,6 @@ export const EditorMenu = ({
|
||||
style={{
|
||||
height: 0,
|
||||
width: '100%',
|
||||
|
||||
marginTop: Platform.OS == 'ios' ? 0 : StatusBar.currentHeight,
|
||||
}}
|
||||
/>
|
||||
@@ -260,7 +304,7 @@ export const EditorMenu = ({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
width: '95%',
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
height: 50,
|
||||
}}>
|
||||
@@ -274,8 +318,8 @@ export const EditorMenu = ({
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<FlatList
|
||||
data={[
|
||||
<View>
|
||||
{[
|
||||
{
|
||||
name: 'Dark Mode',
|
||||
icon: 'moon',
|
||||
@@ -302,10 +346,10 @@ export const EditorMenu = ({
|
||||
name: 'Pinned',
|
||||
icon: 'tag',
|
||||
func: () => {
|
||||
let props = {...noteProps};
|
||||
props.pinned = !noteProps.pinned;
|
||||
|
||||
updateProps(props);
|
||||
if (!timestamp) return;
|
||||
db.pinItem(note.type, note.dateCreated);
|
||||
localRefresh();
|
||||
dispatch({type: ACTIONS.PINNED});
|
||||
},
|
||||
close: false,
|
||||
check: true,
|
||||
@@ -316,10 +360,11 @@ export const EditorMenu = ({
|
||||
name: 'Add to Favorites',
|
||||
icon: 'star',
|
||||
func: () => {
|
||||
let props = {...noteProps};
|
||||
props.favorite = !noteProps.favorite;
|
||||
if (!timestamp) return;
|
||||
|
||||
updateProps(props);
|
||||
db.favoriteItem(note.type, note.dateCreated);
|
||||
localRefresh(item.type);
|
||||
dispatch({type: ACTIONS.FAVORITES});
|
||||
},
|
||||
close: false,
|
||||
check: true,
|
||||
@@ -355,20 +400,17 @@ export const EditorMenu = ({
|
||||
icon: 'lock',
|
||||
func: () => {
|
||||
if (noteProps.locked) {
|
||||
setUnlock(true);
|
||||
//setUnlock(true);
|
||||
} else {
|
||||
setUnlock(false);
|
||||
// setUnlock(false);
|
||||
}
|
||||
setVaultDialog(true);
|
||||
},
|
||||
close: true,
|
||||
check: true,
|
||||
on: noteProps.locked,
|
||||
},
|
||||
]}
|
||||
keyExtractor={(item, index) => item.name}
|
||||
renderItem={_renderListItem}
|
||||
/>
|
||||
].map(_renderListItem)}
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
@@ -377,7 +419,6 @@ export const EditorMenu = ({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-end',
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 15,
|
||||
}}>
|
||||
<View
|
||||
@@ -405,20 +446,21 @@ export const EditorMenu = ({
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<ScrollView
|
||||
ref={ref => (tagsList = ref)}
|
||||
contentContainerStyle={{
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
marginHorizontal: '5%',
|
||||
marginBottom: 0,
|
||||
marginTop: 10,
|
||||
borderRadius: 5,
|
||||
backgroundColor: colors.nav,
|
||||
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
|
||||
style={{
|
||||
backgroundColor: 'transparent',
|
||||
@@ -426,16 +468,16 @@ export const EditorMenu = ({
|
||||
fontFamily: WEIGHT.regular,
|
||||
color: colors.pri,
|
||||
paddingHorizontal: 5,
|
||||
paddingVertical: 2.5,
|
||||
margin: 5,
|
||||
paddingVertical: 1.5,
|
||||
margin: 1,
|
||||
}}
|
||||
blurOnSubmit={false}
|
||||
ref={ref => (tagsInputRef = ref)}
|
||||
placeholderTextColor={colors.icon}
|
||||
onFocus={() => {
|
||||
setFocused(true);
|
||||
}}
|
||||
selectionColor={colors.accent}
|
||||
selectTextOnFocus={true}
|
||||
onBlur={() => {
|
||||
setFocused(false);
|
||||
}}
|
||||
@@ -444,10 +486,10 @@ export const EditorMenu = ({
|
||||
tagToAdd = value;
|
||||
if (tagToAdd.length > 0) backPressCount = 0;
|
||||
}}
|
||||
onKeyPress={_onKeyPress}
|
||||
onSubmitEditing={_onSubmit}
|
||||
onKeyPress={_onKeyPress}
|
||||
/>
|
||||
</ScrollView>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
@@ -456,7 +498,6 @@ export const EditorMenu = ({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-end',
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 15,
|
||||
}}>
|
||||
<View
|
||||
@@ -484,13 +525,14 @@ export const EditorMenu = ({
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<ScrollView
|
||||
contentContainerStyle={{
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
paddingHorizontal: '5%',
|
||||
marginBottom: 15,
|
||||
marginTop: 10,
|
||||
width: '100%',
|
||||
justifyContent: 'space-between',
|
||||
}}>
|
||||
{[
|
||||
'red',
|
||||
@@ -501,7 +543,7 @@ export const EditorMenu = ({
|
||||
'orange',
|
||||
'gray',
|
||||
].map(_renderColor)}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@@ -524,24 +566,6 @@ export const EditorMenu = ({
|
||||
{}
|
||||
<ActivityIndicator color={colors.accent} />
|
||||
</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>
|
||||
</AnimatedSafeAreaView>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
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 {DDS} from '../../../App';
|
||||
import {ph, pv, SIZE, WEIGHT} from '../../common/common';
|
||||
@@ -48,12 +54,10 @@ export default class NoteItem extends React.Component {
|
||||
let {
|
||||
colors,
|
||||
item,
|
||||
width,
|
||||
customStyle,
|
||||
onLongPress,
|
||||
isTrash,
|
||||
pinned,
|
||||
update,
|
||||
index,
|
||||
} = this.props;
|
||||
console.log('rendering', index);
|
||||
@@ -65,9 +69,7 @@ export default class NoteItem extends React.Component {
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
marginHorizontal: 12,
|
||||
width: width,
|
||||
|
||||
maxWidth: '100%',
|
||||
paddingRight: 6,
|
||||
alignSelf: 'center',
|
||||
borderBottomWidth: 1,
|
||||
@@ -110,7 +112,9 @@ export default class NoteItem extends React.Component {
|
||||
vaultDialog: true,
|
||||
});
|
||||
} else {
|
||||
NavigationService.navigate('Editor', {
|
||||
DDS.isTab
|
||||
? DeviceEventEmitter.emit('loadNoteEvent', item)
|
||||
: NavigationService.navigate('Editor', {
|
||||
note: item,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import {NotesPlaceHolder} from '../ListPlaceholders';
|
||||
import NoteItem from '../NoteItem';
|
||||
import SelectionWrapper from '../SelectionWrapper';
|
||||
import PullToRefresh from '../PullToRefresh';
|
||||
import {DDS} from '../../../App';
|
||||
let sectionListRef;
|
||||
export const NotesList = ({
|
||||
onScroll,
|
||||
@@ -25,7 +26,7 @@ export const NotesList = ({
|
||||
<NoteItem
|
||||
colors={colors}
|
||||
customStyle={{
|
||||
width: selectionMode ? w - 74 : '100%',
|
||||
width: selectionMode ? '90%' : '100%',
|
||||
marginHorizontal: 0,
|
||||
}}
|
||||
onLongPress={() => {
|
||||
|
||||
@@ -22,6 +22,7 @@ export const Search = props => {
|
||||
height: 60,
|
||||
justifyContent: 'center',
|
||||
marginTop: props.hide ? -65 : 0,
|
||||
paddingHorizontal: 12,
|
||||
}}>
|
||||
<Animatable.View
|
||||
transition={['borderWidth']}
|
||||
@@ -31,7 +32,7 @@ export const Search = props => {
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingLeft: 12,
|
||||
width: w - 24,
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
borderRadius: br,
|
||||
height: '90%',
|
||||
|
||||
@@ -31,17 +31,21 @@ export const SelectionHeader = ({navigation}) => {
|
||||
style={{
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
height: selectionMode ? 50 + StatusBar.currentHeight : 0,
|
||||
height: selectionMode
|
||||
? Platform.OS === 'android'
|
||||
? 50 + StatusBar.currentHeight
|
||||
: 50
|
||||
: 0,
|
||||
opacity: selectionMode ? 1 : 0,
|
||||
backgroundColor: colors.bg,
|
||||
paddingTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
|
||||
justifyContent: 'flex-end',
|
||||
zIndex: 11,
|
||||
paddingHorizontal: 12,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
width: w - 24,
|
||||
marginHorizontal: 12,
|
||||
width: '100%',
|
||||
height: 50,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
|
||||
@@ -15,21 +15,21 @@ const SelectionWrapper = ({children, item}) => {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: w - 24,
|
||||
|
||||
marginHorizontal: 12,
|
||||
width: '100%',
|
||||
paddingHorizontal: 12,
|
||||
}}>
|
||||
<TouchableOpacity
|
||||
<View
|
||||
onPress={() => {
|
||||
dispatch({type: ACTIONS.SELECTED_ITEMS, item: item});
|
||||
}}
|
||||
style={{
|
||||
width: 50,
|
||||
width: '10%',
|
||||
height: 70,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-start',
|
||||
alignItems: 'center',
|
||||
display: selectionMode ? 'flex' : 'none',
|
||||
opacity: selectionMode ? 1 : 0,
|
||||
paddingRight: 10,
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
@@ -48,7 +48,7 @@ const SelectionWrapper = ({children, item}) => {
|
||||
<Icon size={SIZE.md} color={colors.accent} name="check" />
|
||||
) : null}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{children}
|
||||
</View>
|
||||
|
||||
@@ -7,6 +7,7 @@ import {useTracked} from '../../provider';
|
||||
import NavigationService from '../../services/NavigationService';
|
||||
import {SideMenuEvent} from '../../utils/utils';
|
||||
import {moveNoteHideEvent} from '../DialogManager';
|
||||
import {DDS} from '../../../App';
|
||||
let isOpen = false;
|
||||
export const Header = ({
|
||||
heading,
|
||||
@@ -81,7 +82,7 @@ export const Header = ({
|
||||
) : (
|
||||
undefined
|
||||
)}
|
||||
{menu ? (
|
||||
{menu && !DDS.isTab ? (
|
||||
<TouchableOpacity
|
||||
hitSlop={{top: 20, bottom: 20, left: 50, right: 40}}
|
||||
onPress={() => {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {
|
||||
BackHandler,
|
||||
Dimensions,
|
||||
KeyboardAvoidingView,
|
||||
Linking,
|
||||
Platform,
|
||||
StatusBar,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
DeviceEventEmitter,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import * as Animatable from 'react-native-animatable';
|
||||
import Icon from 'react-native-vector-icons/Feather';
|
||||
@@ -18,29 +19,77 @@ import {
|
||||
ActionSheetEvent,
|
||||
simpleDialogEvent,
|
||||
TEMPLATE_EXIT,
|
||||
_recieveEvent,
|
||||
_unSubscribeEvent,
|
||||
TEMPLATE_EXIT_FULLSCREEN,
|
||||
} from '../../components/DialogManager';
|
||||
import {EditorMenu} from '../../components/EditorMenu';
|
||||
import {useTracked, ACTIONS} from '../../provider';
|
||||
import {SideMenuEvent} from '../../utils/utils';
|
||||
import {SideMenuEvent, w} from '../../utils/utils';
|
||||
import {AnimatedSafeAreaView} from '../Home';
|
||||
|
||||
let EditorWebView;
|
||||
let note = {};
|
||||
var timestamp = null;
|
||||
let timestamp = null;
|
||||
var content = null;
|
||||
var title = null;
|
||||
let timer = null;
|
||||
const Editor = ({navigation}) => {
|
||||
let saveCounter = 0;
|
||||
const Editor = ({navigation, noMenu}) => {
|
||||
// Global State
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Local State
|
||||
const [sidebar, setSidebar] = useState(DDS.isTab ? true : false);
|
||||
let fullscreen = false;
|
||||
|
||||
// FUNCTIONS
|
||||
|
||||
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 => {
|
||||
if (data !== '') {
|
||||
@@ -59,7 +108,7 @@ const Editor = ({navigation}) => {
|
||||
timer = null;
|
||||
onChange(evt.nativeEvent.data);
|
||||
timer = setTimeout(() => {
|
||||
saveNote(true);
|
||||
saveNote.call(this, true);
|
||||
}, 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) {
|
||||
content = {
|
||||
text: '',
|
||||
@@ -81,7 +133,7 @@ const Editor = ({navigation}) => {
|
||||
};
|
||||
}
|
||||
|
||||
timestamp = await db.addNote({
|
||||
let dateCreated = await db.addNote({
|
||||
title,
|
||||
content: {
|
||||
text: content.text,
|
||||
@@ -89,21 +141,60 @@ const Editor = ({navigation}) => {
|
||||
},
|
||||
dateCreated: timestamp,
|
||||
});
|
||||
if (timestamp !== dateCreated) {
|
||||
timestamp = dateCreated;
|
||||
}
|
||||
|
||||
if (lockNote && db.getNote(timestamp).locked) {
|
||||
db.lockNote(timestamp, 'password');
|
||||
if (content.text.length < 200 || saveCounter < 2) {
|
||||
dispatch({
|
||||
type: ACTIONS.NOTES,
|
||||
});
|
||||
}
|
||||
saveCounter++;
|
||||
if (timestamp) {
|
||||
let lockednote = db.getNote(timestamp);
|
||||
if (lockNote && lockednote.locked) {
|
||||
await db.lockNote(timestamp, 'password');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onWebViewLoad = () => {
|
||||
post(JSON.stringify(colors));
|
||||
if (navigation.state.params && navigation.state.params.note) {
|
||||
if (noMenu) {
|
||||
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;
|
||||
updateEditor();
|
||||
} else if (note && note.dateCreated) {
|
||||
updateEditor();
|
||||
}
|
||||
|
||||
post(JSON.stringify(colors));
|
||||
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const updateEditor = () => {
|
||||
title = note.title;
|
||||
timestamp = note.dateCreated;
|
||||
content = note.content;
|
||||
saveCounter = 0;
|
||||
post(JSON.stringify(note.content.delta));
|
||||
post(
|
||||
JSON.stringify({
|
||||
@@ -111,12 +202,10 @@ const Editor = ({navigation}) => {
|
||||
value: note.title,
|
||||
}),
|
||||
);
|
||||
title = note.title;
|
||||
timestamp = note.dateCreated;
|
||||
content = note.content;
|
||||
};
|
||||
|
||||
const params = 'platform=' + Platform.OS;
|
||||
|
||||
const sourceUri =
|
||||
(Platform.OS === 'android' ? 'file:///android_asset/' : '') +
|
||||
'Web.bundle/loader.html';
|
||||
@@ -132,18 +221,45 @@ const Editor = ({navigation}) => {
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : null}
|
||||
style={{
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
backgroundColor: 'transparent',
|
||||
}}>
|
||||
<View
|
||||
style={{
|
||||
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
|
||||
}}
|
||||
/>
|
||||
|
||||
<Animatable.View
|
||||
transition={['translateX', 'opacity']}
|
||||
duration={300}
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
zIndex: 999,
|
||||
position: 'absolute',
|
||||
backgroundColor: colors.bg,
|
||||
opacity: loading ? 1 : 0,
|
||||
transform: [
|
||||
{
|
||||
translateX: loading ? 0 : w * 1.5,
|
||||
},
|
||||
],
|
||||
}}>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={colors.accent} size={SIZE.xxl} />
|
||||
) : null}
|
||||
</Animatable.View>
|
||||
|
||||
{noMenu ? null : (
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
simpleDialogEvent(TEMPLATE_EXIT('Editor'));
|
||||
}}
|
||||
style={{
|
||||
width: '12.5%',
|
||||
width: 60,
|
||||
height: 50,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-start',
|
||||
@@ -152,23 +268,44 @@ const Editor = ({navigation}) => {
|
||||
top: 0,
|
||||
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
|
||||
paddingLeft: 12,
|
||||
zIndex: 999,
|
||||
zIndex: 800,
|
||||
}}>
|
||||
<Icon
|
||||
style={{
|
||||
marginLeft: -7,
|
||||
marginTop: -3.5,
|
||||
}}
|
||||
name="chevron-left"
|
||||
color={colors.icon}
|
||||
size={SIZE.xxxl - 3}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
DDS.isTab
|
||||
? setSidebar(!sidebar)
|
||||
: ActionSheetEvent(
|
||||
if (fullscreen) {
|
||||
DeviceEventEmitter.emit('closeFullScreenEditor');
|
||||
fullscreen = false;
|
||||
post(
|
||||
JSON.stringify({
|
||||
type: 'nomenu',
|
||||
value: true,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
DeviceEventEmitter.emit('showFullScreenEditor');
|
||||
fullscreen = true;
|
||||
post(
|
||||
JSON.stringify({
|
||||
type: 'nomenu',
|
||||
value: false,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
ActionSheetEvent(
|
||||
note,
|
||||
true,
|
||||
true,
|
||||
@@ -177,7 +314,7 @@ const Editor = ({navigation}) => {
|
||||
);
|
||||
}}
|
||||
style={{
|
||||
width: '12.5%',
|
||||
width: 60,
|
||||
height: 50,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-end',
|
||||
@@ -186,7 +323,7 @@ const Editor = ({navigation}) => {
|
||||
top: 0,
|
||||
marginTop: Platform.OS === 'ios' ? 0 : StatusBar.currentHeight,
|
||||
paddingRight: 12,
|
||||
zIndex: 999,
|
||||
zIndex: 800,
|
||||
}}>
|
||||
<Icon name="more-horizontal" color={colors.icon} size={SIZE.xxxl} />
|
||||
</TouchableOpacity>
|
||||
@@ -196,7 +333,8 @@ const Editor = ({navigation}) => {
|
||||
onError={error => console.log(error)}
|
||||
onLoad={onWebViewLoad}
|
||||
javaScriptEnabled
|
||||
onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest}
|
||||
injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null}
|
||||
//onShouldStartLoadWithRequest={_onShouldStartLoadWithRequest}
|
||||
renderLoading={() => (
|
||||
<View
|
||||
style={{
|
||||
@@ -206,22 +344,19 @@ const Editor = ({navigation}) => {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
cacheEnabled={true}
|
||||
cacheMode="LOAD_NO_CACHE"
|
||||
cacheEnabled={false}
|
||||
domStorageEnabled
|
||||
scrollEnabled={false}
|
||||
bounces={true}
|
||||
allowFileAccess={true}
|
||||
scalesPageToFit={true}
|
||||
allowFileAccessFromFileURLs={true}
|
||||
allowUniversalAccessFromFileURLs={true}
|
||||
originWhitelist={'*'}
|
||||
injectedJavaScript={Platform.OS === 'ios' ? injectedJS : null}
|
||||
source={
|
||||
Platform.OS === 'ios'
|
||||
? {uri: sourceUri}
|
||||
: {
|
||||
uri: 'file:///android_asset/texteditor.html',
|
||||
baseUrl: 'baseUrl:"file:///android_asset/',
|
||||
}
|
||||
}
|
||||
source={{
|
||||
uri: 'http://192.168.10.9:8080/texteditor.html',
|
||||
}}
|
||||
style={{
|
||||
height: '100%',
|
||||
maxHeight: '100%',
|
||||
@@ -236,24 +371,35 @@ const Editor = ({navigation}) => {
|
||||
// EFFECTS
|
||||
|
||||
useEffect(() => {
|
||||
let handleBack = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
simpleDialogEvent(TEMPLATE_EXIT('Editor'));
|
||||
|
||||
let handleBack;
|
||||
if (!noMenu) {
|
||||
handleBack = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN());
|
||||
return true;
|
||||
});
|
||||
return () => {
|
||||
} else {
|
||||
if (handleBack) {
|
||||
handleBack.remove();
|
||||
handleBack = null;
|
||||
}
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (handleBack) {
|
||||
handleBack.remove();
|
||||
handleBack = null;
|
||||
}
|
||||
title = null;
|
||||
content = null;
|
||||
timer = null;
|
||||
timestamp = null;
|
||||
};
|
||||
}, []);
|
||||
}, [noMenu]);
|
||||
|
||||
useEffect(() => {
|
||||
SideMenuEvent.disable();
|
||||
noMenu ? null : SideMenuEvent.disable();
|
||||
|
||||
return () => {
|
||||
if (noMenu) return;
|
||||
DDS.isTab ? SideMenuEvent.open() : null;
|
||||
SideMenuEvent.enable();
|
||||
};
|
||||
@@ -271,18 +417,11 @@ const Editor = ({navigation}) => {
|
||||
flex: 1,
|
||||
backgroundColor: colors.bg,
|
||||
height: '100%',
|
||||
width: sidebar ? '70%' : '100%',
|
||||
width: '100%',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
}}>
|
||||
{_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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ import {ACTIONS, useTracked} from '../../provider';
|
||||
import {slideLeft, slideRight} from '../../utils/animations';
|
||||
import {w} from '../../utils/utils';
|
||||
import {AddNotebookEvent} from '../../components/DialogManager';
|
||||
import {DDS} from '../../../App';
|
||||
|
||||
export const Folders = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
@@ -171,7 +172,7 @@ export const Folders = ({navigation}) => {
|
||||
<View
|
||||
style={{
|
||||
height: '80%',
|
||||
width: '100%',
|
||||
width: DDS.isTab ? '70%' : '100%',
|
||||
alignItems: 'center',
|
||||
alignSelf: 'center',
|
||||
justifyContent: 'center',
|
||||
@@ -204,6 +205,7 @@ export const Folders = ({navigation}) => {
|
||||
contentContainerStyle={{
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
minHeight: '100%',
|
||||
}}
|
||||
ListFooterComponent={
|
||||
<View
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 {db} from '../../../App';
|
||||
import {db, DDS} from '../../../App';
|
||||
import Container from '../../components/Container';
|
||||
import {Header} from '../../components/header';
|
||||
import {NotesList} from '../../components/NotesList';
|
||||
@@ -12,6 +12,7 @@ import NavigationService from '../../services/NavigationService';
|
||||
import {SideMenuEvent, ToastEvent} from '../../utils/utils';
|
||||
import {useIsFocused} from 'react-navigation-hooks';
|
||||
import PullToRefresh from '../../components/PullToRefresh';
|
||||
import Editor from '../Editor';
|
||||
|
||||
export const AnimatedSafeAreaView = Animatable.createAnimatableComponent(
|
||||
SafeAreaView,
|
||||
@@ -100,9 +101,14 @@ export const Home = ({navigation}) => {
|
||||
bottomButtonText="Add a new note"
|
||||
bottomButtonOnPress={() => {
|
||||
dispatch({type: ACTIONS.NOTES});
|
||||
|
||||
if (DDS.isTab) {
|
||||
DeviceEventEmitter.emit('loadNoteEvent', {type: 'new'});
|
||||
} else {
|
||||
SideMenuEvent.close();
|
||||
SideMenuEvent.disable();
|
||||
NavigationService.navigate('Editor');
|
||||
}
|
||||
}}>
|
||||
<SelectionHeader />
|
||||
<Animatable.View
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
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 {FlatList} from 'react-native-gesture-handler';
|
||||
import Icon from 'react-native-vector-icons/Feather';
|
||||
@@ -12,10 +18,11 @@ import {
|
||||
pv,
|
||||
SIZE,
|
||||
WEIGHT,
|
||||
setColorScheme,
|
||||
} from '../../common/common';
|
||||
import Container from '../../components/Container';
|
||||
import {Header} from '../../components/header';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useTracked, ACTIONS} from '../../provider';
|
||||
import NavigationService from '../../services/NavigationService';
|
||||
export const Settings = ({navigation}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
|
||||
Reference in New Issue
Block a user