import React, { createRef, useEffect, useState } from 'react'; import { Keyboard, TextInput, TouchableOpacity, View } from 'react-native'; import { FlatList } from 'react-native-gesture-handler'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import { notesnook } from '../../../e2e/test.ids'; import { useTracked } from '../../provider'; import { Actions } from '../../provider/Actions'; import { useNotebookStore, useSelectionStore, useSettingStore } from '../../provider/stores'; import { eSubscribeEvent, eUnSubscribeEvent, sendNoteEditedEvent, ToastEvent } from '../../services/EventManager'; import Navigation from '../../services/Navigation'; import { getTotalNotes, InteractionManager } from '../../utils'; import { db } from '../../utils/database'; import { eOpenMoveNoteDialog } from '../../utils/Events'; import { pv, SIZE } from '../../utils/SizeUtils'; import SheetWrapper from '../Sheet'; import { Button } from '../Button'; import DialogHeader from '../Dialog/dialog-header'; import { PressableButton } from '../PressableButton'; import Heading from '../Typography/Heading'; import Paragraph from '../Typography/Paragraph'; import Input from '../Input'; import { ActionIcon } from '../ActionIcon'; import { Dialog } from '../Dialog'; import { presentDialog } from '../Dialog/functions'; import layoutmanager from '../../utils/layout-manager'; let newNotebookTitle = null; let newTopicTitle = null; const notebookInput = createRef(); const topicInput = createRef(); const actionSheetRef = createRef(); const MoveNoteDialog = () => { const [visible, setVisible] = useState(false); const [note, setNote] = useState(null); function open(note) { setNote(note); setVisible(true); actionSheetRef.current?.setModalVisible(true); } const close = () => { actionSheetRef.current?.setModalVisible(false); }; useEffect(() => { eSubscribeEvent(eOpenMoveNoteDialog, open); return () => { eUnSubscribeEvent(eOpenMoveNoteDialog, open); }; }, []); const _onClose = () => { setVisible(false); newTopicTitle = null; newNotebookTitle = null; setNote(null); Navigation.setRoutesToUpdate([ Navigation.routeNames.Notes, Navigation.routeNames.Favorites, Navigation.routeNames.NotesPage, Navigation.routeNames.Notebook, Navigation.routeNames.Notebooks ]); }; const update = note => { setNote(note); }; return !visible ? null : ( ); }; export default MoveNoteDialog; const MoveNoteComponent = ({ close, note, setNote }) => { const [state, dispatch] = useTracked(); const { colors } = state; const nbs = useNotebookStore(state => state.notebooks.filter(n => n?.type === 'notebook')); let notebooks = [...db.notebooks.all]; const selectedItemsList = useSelectionStore(state => state.selectedItemsList); const setNotebooks = useNotebookStore(state => state.setNotebooks); const [expanded, setExpanded] = useState(''); const [notebookInputFocused, setNotebookInputFocused] = useState(false); const [noteExists, setNoteExists] = useState([]); const addNewNotebook = async () => { if (!newNotebookTitle || newNotebookTitle.trim().length === 0) return ToastEvent.show({ heading: 'Notebook title is required', type: 'error', context: 'local' }); let id = await db.notebooks.add({ title: newNotebookTitle, description: null, topics: [], id: null }); console.log('added notebook id', id); setExpanded(id); openAddTopicDialog(db.notebooks.notebook(id).data); notebookInput.current?.clear(); notebookInput.current?.blur(); setNotebooks(); updateNoteExists(); }; const addNewTopic = async (value, item) => { if (!value || value.trim().length === 0) { ToastEvent.show({ heading: 'Topic title is required', type: 'error', context: 'local' }); return false; } console.log(item.id); await db.notebooks.notebook(item.id).topics.add(value); setNotebooks(); updateNoteExists(); return true; }; const handlePress = async (item, index) => { if (note && item.notes.indexOf(note.id) > -1) { await db.notebooks.notebook(item.notebookId).topics.topic(item.id).delete(note.id); if (note && note.id) { setNote({ ...db.notes.note(note.id).data }); requestAnimationFrame(() => { //layoutmanager.withSpringAnimation(500); Navigation.setRoutesToUpdate([ Navigation.routeNames.NotesPage, Navigation.routeNames.Favorites, Navigation.routeNames.Notes ]); }); } setNotebooks(); updateNoteExists(); return; } let noteIds = []; selectedItemsList.forEach(i => noteIds.push(i.id)); await db.notes.move( { topic: item.id, id: item.notebookId }, ...noteIds ); if (note && note.id) { setNote({ ...db.notes.note(note.id).data }); requestAnimationFrame(() => { //layoutmanager.withSpringAnimation(500); Navigation.setRoutesToUpdate([ Navigation.routeNames.NotesPage, Navigation.routeNames.Favorites, Navigation.routeNames.Notes ]); }); } setNotebooks(); updateNoteExists(); }; useEffect(() => { updateNoteExists(); }, []); const updateNoteExists = () => { if (!note?.id) return; let ids = []; let notebooks = db.notebooks.all; for (let i = 0; i < notebooks.length; i++) { if (notebooks[i].topics) { for (let t = 0; t < notebooks[i].topics.length; t++) { if (notebooks[i].topics[t].notes.indexOf(note.id) > -1) { ids.push(notebooks[i].id); } } } } setNoteExists(ids); }; const openAddTopicDialog = item => { presentDialog({ context: 'move_note', input: true, inputPlaceholder: 'Enter title', title: 'New topic', paragraph: 'Add a new topic in ' + item.title, positiveText: 'Add', positivePress: value => { return addNewTopic(value, item); } }); }; return ( <> { Keyboard.dismiss(); }} /> { actionSheetRef.current?.handleChildScrollEnd(); }} onMomentumScrollEnd={() => { actionSheetRef.current?.handleChildScrollEnd(); }} onScrollAnimationEnd={() => { actionSheetRef.current?.handleChildScrollEnd(); }} keyboardShouldPersistTaps="always" keyboardDismissMode="none" data={notebooks} ListFooterComponent={ } ListHeaderComponent={ { newNotebookTitle = value; }} testID={notesnook.ids.dialogs.addTo.addNotebook} blurOnSubmit={false} onFocusInput={() => { setNotebookInputFocused(true); }} onBlurInput={() => { setNotebookInputFocused(false); }} button={{ icon: 'check', color: notebookInputFocused ? colors.accent : colors.icon, onPress: addNewNotebook }} onSubmit={addNewNotebook} placeholder="Create a new notebook" /> } style={{ paddingHorizontal: 12 }} renderItem={({ item, index }) => ( { if (!item.topics || item.topics.length === 0) { setExpanded(item.id); openAddTopicDialog(item); return; } layoutmanager.withAnimation(200); setExpanded(item.id === expanded ? null : item.id); setNotebookInputFocused(false); }} type="grayBg" customStyle={{ height: 50, width: '100%', borderRadius: 5, alignItems: 'flex-start' }} > -1 ? colors.accent : null} size={SIZE.md} > {item.title} {item.topics?.length > 0 ? ( {getTotalNotes(item) + ' notes' + ' & '} {item.topics.length === 1 ? item.topics.length + ' topic' : item.topics.length + ' topics'} ) : null} { if (expanded !== item.id) { setExpanded(item.id); return; } layoutmanager.withAnimation(200); setExpanded(item.id); openAddTopicDialog(item); }} /> {expanded === item.id ? ( { actionSheetRef.current?.handleChildScrollEnd(); }} onMomentumScrollEnd={() => { actionSheetRef.current?.handleChildScrollEnd(); }} onScrollAnimationEnd={() => { actionSheetRef.current?.handleChildScrollEnd(); }} style={{ width: '100%', alignSelf: 'flex-end', maxHeight: 500 }} renderItem={({ item, index }) => ( handlePress(item, index)} type="gray" customStyle={{ height: 50, borderTopWidth: index === 0 ? 0 : 1, borderTopColor: index === 0 ? null : colors.nav, width: '100%', borderRadius: 0, alignItems: 'center', flexDirection: 'row', paddingHorizontal: 12, justifyContent: 'space-between' }} > {item.title} {item.notes.length + ' notes'} {note && item.notes.indexOf(note.id) > -1 ? (