Files
notesnook/apps/mobile/src/components/MoveNoteDialog/index.js

412 lines
15 KiB
JavaScript
Raw Normal View History

2020-09-14 17:10:02 +05:00
import React, {createRef, useEffect, useState} from 'react';
2020-11-23 15:57:31 +05:00
import {
FlatList,
KeyboardAvoidingView,
Modal,
SafeAreaView,
TextInput,
TouchableOpacity,
View,
} from 'react-native';
2020-09-14 17:10:02 +05:00
import {useSafeAreaInsets} from 'react-native-safe-area-context';
2020-09-14 16:45:41 +05:00
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
2020-12-01 22:52:01 +05:00
import { notesnook } from '../../../e2e/test.ids';
2020-09-14 17:10:02 +05:00
import {useTracked} from '../../provider';
2020-10-13 17:02:14 +05:00
import {Actions} from '../../provider/Actions';
2020-11-23 12:32:33 +05:00
import {DDS} from '../../services/DeviceDetection';
2020-11-20 01:23:05 +05:00
import {
eSubscribeEvent,
eUnSubscribeEvent,
ToastEvent,
} from '../../services/EventManager';
2020-10-13 17:02:14 +05:00
import {getElevation} from '../../utils';
2020-11-23 12:32:33 +05:00
import {db} from '../../utils/DB';
import {eOpenMoveNoteDialog} from '../../utils/Events';
import {pv, SIZE, WEIGHT} from '../../utils/SizeUtils';
2020-11-23 15:57:31 +05:00
import DialogButtons from '../Dialog/dialog-buttons';
import DialogHeader from '../Dialog/dialog-header';
2020-09-14 17:10:02 +05:00
import {PressableButton} from '../PressableButton';
import {Toast} from '../Toast';
2020-11-20 01:23:05 +05:00
import Heading from '../Typography/Heading';
import Paragraph from '../Typography/Paragraph';
let newNotebookTitle = null;
let newTopicTitle = null;
const notebookInput = createRef();
const topicInput = createRef();
2020-09-14 16:45:41 +05:00
const MoveNoteDialog = () => {
const [state, dispatch] = useTracked();
const {notebooks, colors, selectedItemsList} = state;
2020-09-14 17:10:02 +05:00
const [visible, setVisible] = useState(false);
2020-09-14 16:45:41 +05:00
const [expanded, setExpanded] = useState('');
const [notebookInputFocused, setNotebookInputFocused] = useState(false);
const [topicInputFocused, setTopicInputFocused] = useState(false);
2020-09-14 16:45:41 +05:00
function open() {
setVisible(true);
}
2020-01-18 18:13:34 +05:00
2020-09-14 16:45:41 +05:00
const close = () => {
setVisible(false);
setExpanded(false);
newTopicTitle = null;
newNotebookTitle = null;
setNotebookInputFocused(false);
setTopicInputFocused(false);
2020-09-14 16:45:41 +05:00
};
2020-01-18 18:13:34 +05:00
2020-09-14 16:45:41 +05:00
useEffect(() => {
eSubscribeEvent(eOpenMoveNoteDialog, open);
return () => {
eUnSubscribeEvent(eOpenMoveNoteDialog, open);
2020-01-18 18:13:34 +05:00
};
2020-09-14 16:45:41 +05:00
}, []);
2020-01-18 18:13:34 +05:00
2020-09-14 16:45:41 +05:00
const addNewNotebook = async () => {
if (!newNotebookTitle || newNotebookTitle.trim().length === 0)
return ToastEvent.show('Title is required', 'error', 'local');
2020-01-18 18:13:34 +05:00
2020-09-14 16:45:41 +05:00
await db.notebooks.add({
title: newNotebookTitle,
description: 'this.description',
topics: [],
id: null,
2020-01-18 18:13:34 +05:00
});
notebookInput.current?.clear();
notebookInput.current?.blur();
2020-10-13 17:02:14 +05:00
dispatch({type: Actions.NOTEBOOKS});
dispatch({type: Actions.PINNED});
2020-09-14 16:45:41 +05:00
};
2020-01-18 18:13:34 +05:00
2020-09-14 16:45:41 +05:00
const addNewTopic = async () => {
if (!newTopicTitle || newTopicTitle.trim().length === 0) {
2020-09-14 16:45:41 +05:00
return ToastEvent.show('Title is required', 'error', 'local');
}
let res = await db.notebooks.notebook(expanded).topics.add(newTopicTitle);
2020-10-13 17:02:14 +05:00
dispatch({type: Actions.NOTEBOOKS});
dispatch({type: Actions.PINNED});
topicInput.current?.clear();
topicInput.current?.blur();
newTopicTitle = null;
2020-09-14 16:45:41 +05:00
};
2020-11-23 12:32:33 +05:00
return !visible ? null : (
2020-09-14 16:45:41 +05:00
<Modal
animated={true}
animationType="slide"
onRequestClose={close}
2020-11-23 12:32:33 +05:00
visible={true}
2020-09-14 16:45:41 +05:00
transparent={true}>
2020-11-23 15:57:31 +05:00
<SafeAreaView
2020-09-14 16:45:41 +05:00
style={{
height: '100%',
2020-11-23 15:57:31 +05:00
width: '100%',
2020-09-14 16:45:41 +05:00
}}>
2020-11-23 15:57:31 +05:00
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : null}
2020-01-18 18:13:34 +05:00
style={{
2020-11-23 15:57:31 +05:00
flex: 1,
backgroundColor: DDS.isTab ? 'rgba(0,0,0,0.3)' : colors.bg,
2020-01-23 23:19:06 +05:00
width: '100%',
height: '100%',
2020-11-23 15:57:31 +05:00
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
2020-09-14 16:45:41 +05:00
}}>
2020-11-23 15:57:31 +05:00
<TouchableOpacity
onPress={close}
style={{
width: '100%',
height: '100%',
position: 'absolute',
zIndex: 1,
}}
/>
2020-01-23 23:19:06 +05:00
<View
style={{
2020-11-23 15:57:31 +05:00
...getElevation(DDS.isTab ? 10 : 0),
width: DDS.isTab ? 500 : '100%',
height: DDS.isTab ? 500 : '100%',
flex: 1,
borderRadius: DDS.isTab ? 5 : 0,
backgroundColor: colors.bg,
padding: DDS.isTab ? 8 : 0,
zIndex: 10,
paddingVertical: 12,
2020-01-23 23:19:06 +05:00
}}>
2020-11-23 15:57:31 +05:00
<View
2020-09-14 16:45:41 +05:00
style={{
2020-11-23 15:57:31 +05:00
paddingHorizontal: 12,
}}>
<DialogHeader
title="Add to notebook"
paragraph={`Organize your notes to find them easily.`}
/>
</View>
2020-09-14 16:45:41 +05:00
2020-11-23 15:57:31 +05:00
<FlatList
data={state.notebooks}
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
ListHeaderComponent={
2020-09-14 16:45:41 +05:00
<View
style={{
paddingHorizontal: 12,
}}>
<View
style={{
2020-11-23 15:57:31 +05:00
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 0,
marginBottom: 10,
2020-09-14 16:45:41 +05:00
width: '100%',
2020-11-23 15:57:31 +05:00
borderBottomWidth: 1,
borderColor: notebookInputFocused
? colors.accent
: colors.nav,
2020-09-14 16:45:41 +05:00
}}>
2020-11-23 15:57:31 +05:00
<TextInput
ref={notebookInput}
onChangeText={(value) => {
newNotebookTitle = value;
}}
2020-12-01 22:52:01 +05:00
testID={notesnook.ids.dialogs.addTo.addNotebook}
2020-11-23 15:57:31 +05:00
blurOnSubmit={false}
onFocus={() => {
setNotebookInputFocused(true);
}}
onBlur={() => {
setNotebookInputFocused(false);
}}
onSubmitEditing={addNewNotebook}
style={[
{
color: colors.pri,
width: '85%',
maxWidth: '85%',
paddingHorizontal: 0,
borderRadius: 5,
minHeight: 45,
fontSize: SIZE.md,
fontFamily: WEIGHT.regular,
padding: pv - 2,
},
]}
placeholder="Add a notebook"
placeholderTextColor={colors.icon}
/>
<TouchableOpacity
onPress={addNewNotebook}
2020-12-01 22:52:01 +05:00
testID={notesnook.ids.dialogs.addTo.addNotebook}
2020-11-23 15:57:31 +05:00
style={[
{
borderRadius: 5,
width: '12%',
minHeight: 45,
justifyContent: 'center',
alignItems: 'center',
},
]}>
<Icon
name="plus"
size={SIZE.lg}
color={
notebookInputFocused ? colors.accent : colors.icon
}
/>
</TouchableOpacity>
2020-09-14 16:45:41 +05:00
</View>
2020-11-23 15:57:31 +05:00
</View>
}
renderItem={({item, index}) => (
<View>
<PressableButton
onPress={() => {
setExpanded(item.id === expanded ? null : item.id);
}}
2020-12-01 17:51:39 +05:00
type={expanded === item.id ? 'shade' : 'transparent'}
2020-11-23 15:57:31 +05:00
customStyle={{
height: 50,
width: '100%',
borderRadius: 0,
alignItems: 'flex-start',
paddingHorizontal: 12,
marginBottom: 5,
}}>
<View
style={{
borderBottomWidth: 1,
width: '100%',
height: 50,
justifyContent: 'center',
borderBottomColor:
expanded === item.id ? 'transparent' : colors.nav,
}}>
<Heading size={SIZE.md}>
{item.title}
{'\n'}
<Paragraph size={SIZE.xs} color={colors.icon}>
{item.totalNotes +
' notes' +
' & ' +
item.topics.length +
' topics'}
</Paragraph>
</Heading>
</View>
</PressableButton>
2020-09-14 16:45:41 +05:00
2020-11-23 15:57:31 +05:00
{expanded === item.id ? (
<FlatList
data={item.topics}
keyboardShouldPersistTaps="always"
keyboardDismissMode="none"
ListHeaderComponent={
2020-09-14 16:45:41 +05:00
<View
style={{
2020-11-23 15:57:31 +05:00
paddingRight: 12,
2020-09-14 16:45:41 +05:00
}}>
2020-11-23 15:57:31 +05:00
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
width: '90%',
alignSelf: 'flex-end',
marginBottom: 5,
marginTop: 5,
borderBottomWidth: 1,
borderColor: topicInputFocused
? colors.accent
: colors.nav,
}}>
<TextInput
ref={topicInput}
onChangeText={(value) => {
newTopicTitle = value;
}}
2020-12-01 22:52:01 +05:00
testID={notesnook.ids.dialogs.addTo.addTopic}
2020-11-23 15:57:31 +05:00
blurOnSubmit={false}
onFocus={() => {
setTopicInputFocused(true);
}}
onBlur={() => {
setTopicInputFocused(false);
}}
onSubmitEditing={addNewTopic}
style={[
{
color: colors.pri,
width: '85%',
maxWidth: '85%',
paddingHorizontal: 0,
borderRadius: 5,
height: 40,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
padding: pv - 2,
},
]}
placeholder="Add a Topic"
placeholderTextColor={colors.icon}
2020-09-14 16:45:41 +05:00
/>
2020-11-23 15:57:31 +05:00
<TouchableOpacity
onPress={addNewTopic}
2020-12-01 22:52:01 +05:00
testID={notesnook.ids.dialogs.addTo.btnTopic}
2020-11-23 15:57:31 +05:00
style={[
{
borderRadius: 5,
width: 40,
minHeight: 40,
justifyContent: 'center',
alignItems: 'center',
},
]}>
<Icon
name="plus"
size={SIZE.lg}
color={
topicInputFocused
? colors.accent
: colors.icon
}
/>
</TouchableOpacity>
</View>
2020-09-14 16:45:41 +05:00
</View>
2020-11-23 15:57:31 +05:00
}
renderItem={({item, index}) => (
<PressableButton
onPress={async () => {
let noteIds = [];
selectedItemsList.forEach((i) =>
noteIds.push(i.id),
);
2020-09-28 09:50:12 +05:00
2020-11-23 15:57:31 +05:00
let res = await db.notes.move(
{
topic: item.title,
id: item.notebookId,
},
...noteIds,
);
dispatch({type: Actions.CLEAR_SELECTION});
dispatch({type: Actions.NOTEBOOKS});
dispatch({type: Actions.PINNED});
close();
let notebookName = db.notebooks.notebook(
item.notebookId,
).title;
ToastEvent.show(
`Note moved to ${item.title} in ${notebookName}`,
'success',
);
}}
2020-12-01 17:51:39 +05:00
type="gray"
2020-11-23 15:57:31 +05:00
customStyle={{
height: 50,
borderTopWidth: index === 0 ? 0 : 1,
borderTopColor: colors.nav,
width: '87%',
alignSelf: 'flex-end',
borderRadius: 0,
alignItems: 'center',
marginRight: 12,
flexDirection: 'row',
justifyContent: 'space-between',
}}>
<Paragraph color={colors.heading}>
{item.title}
{'\n'}
<Paragraph color={colors.icon} size={SIZE.xs}>
{item.totalNotes + ' notes'}
</Paragraph>
2020-11-20 01:23:05 +05:00
</Paragraph>
2020-11-23 15:57:31 +05:00
</PressableButton>
)}
/>
) : null}
</View>
)}
/>
2020-12-01 11:19:29 +05:00
<View
style={{
paddingHorizontal: 12,
2020-12-01 17:51:39 +05:00
width: '100%',
2020-12-01 11:19:29 +05:00
}}>
<DialogButtons negativeTitle="Cancel" onPressNegative={close} />
</View>
2020-11-23 15:57:31 +05:00
</View>
<Toast context="local" />
</KeyboardAvoidingView>
</SafeAreaView>
2020-09-14 16:45:41 +05:00
</Modal>
);
};
2020-01-18 18:13:34 +05:00
export default MoveNoteDialog;