diff --git a/apps/mobile/App.js b/apps/mobile/App.js index 7aea56c3b..7905d4c2a 100644 --- a/apps/mobile/App.js +++ b/apps/mobile/App.js @@ -39,6 +39,7 @@ import Animated, {Easing} from 'react-native-reanimated'; import {useForceUpdate} from './src/views/ListsEditor'; import FastStorage from 'react-native-fast-storage'; import {defaultState} from './src/provider/defaultState'; +import {EditorPosition} from './src/utils/animations'; export const DDS = new DeviceDetectionService(); export const db = new Storage(StorageInterface); @@ -176,9 +177,9 @@ const App = () => { } else { s = JSON.parse(s); scale.fontScale = s.fontScale; - console.log(scale.fontScale); + updateSize(); - console.log(SIZE.lg); + dispatch({type: ACTIONS.SETTINGS, settings: {...s}}); } dispatch({type: ACTIONS.THEME, colors: newColors}); @@ -367,7 +368,27 @@ const App = () => { /> )} + + (editorRef = ref)} + style={{ + width: '100%', + height: '100%', + position: 'absolute', + zIndex: 10, + backgroundColor: colors.bg, + elevation: 10, + transform: [ + { + translateX: EditorPosition, + }, + ], + }}> + + + + diff --git a/apps/mobile/src/components/NoteItem/index.js b/apps/mobile/src/components/NoteItem/index.js index 11b55ec7c..38b0e45a6 100644 --- a/apps/mobile/src/components/NoteItem/index.js +++ b/apps/mobile/src/components/NoteItem/index.js @@ -12,6 +12,7 @@ import { simpleDialogEvent, TEMPLATE_TRASH, } from '../DialogManager'; +import {openEditorAnimation} from '../../utils/animations'; const w = Dimensions.get('window').width; const h = Dimensions.get('window').height; @@ -116,14 +117,15 @@ export default class NoteItem extends React.Component { onPress={() => { if (item.locked) { eSendEvent(eOpenVaultDialog, {unlock: true, i: item}); + return; + } + if (DDS.isTab) { + eSendEvent(eOnLoadNote, item); + } else if (isTrash) { + simpleDialogEvent(TEMPLATE_TRASH(item.type)); } else { - DDS.isTab - ? eSendEvent(eOnLoadNote, item) - : isTrash - ? simpleDialogEvent(TEMPLATE_TRASH(item.type)) - : NavigationService.navigate('Editor', { - note: item, - }); + eSendEvent(eOnLoadNote, item); + openEditorAnimation(); } }} style={{ diff --git a/apps/mobile/src/components/Toast/index.js b/apps/mobile/src/components/Toast/index.js index 5bc743650..61befb6d5 100644 --- a/apps/mobile/src/components/Toast/index.js +++ b/apps/mobile/src/components/Toast/index.js @@ -65,16 +65,17 @@ export const Toast = () => { return ( { }}> { borderRadius: 5, paddingHorizontal: ph, paddingVertical: pv, + opacity: toast ? 1 : 0, justifyContent: 'center', elevation: 25, flexDirection: 'row', diff --git a/apps/mobile/src/utils/animations.js b/apps/mobile/src/utils/animations.js index 0b2159f40..2b3ad2671 100644 --- a/apps/mobile/src/utils/animations.js +++ b/apps/mobile/src/utils/animations.js @@ -1,3 +1,28 @@ +import Animated, {Easing} from 'react-native-reanimated'; +import {Dimensions} from 'react-native'; + +const {color, Value, timing} = Animated; + +export const EditorPosition = new Value(Dimensions.get('window').width * 1.5); + +export function openEditorAnimation() { + let openConfigH = { + duration: 300, + toValue: 0, + easing: Easing.inOut(Easing.ease), + }; + timing(EditorPosition, openConfigH).start(); +} + +export function exitEditorAnimation() { + let openConfigH = { + duration: 300, + toValue: Dimensions.get('window').width * 1.5, + easing: Easing.inOut(Easing.ease), + }; + timing(EditorPosition, openConfigH).start(); +} + export const slideRight = { 0: { transform: [{translateX: -4}], diff --git a/apps/mobile/src/utils/utils.js b/apps/mobile/src/utils/utils.js index b4da56aeb..d10b6e84e 100755 --- a/apps/mobile/src/utils/utils.js +++ b/apps/mobile/src/utils/utils.js @@ -58,7 +58,7 @@ export const w = Dimensions.get('window').width; export const h = Dimensions.get('window').height; export const ToastEvent = { - show: (message, type, duration = 1000, func = null, actionText = '') => { + show: (message, type, duration = 3000, func = null, actionText = '') => { eSendEvent(eShowToast, { message, type, @@ -67,7 +67,7 @@ export const ToastEvent = { actionText, }); }, - hide: (message, type, duration = 1000, func = null, actionText = '') => { + hide: (message, type, duration = 3000, func = null, actionText = '') => { eSendEvent(eHideToast, { message, type, diff --git a/apps/mobile/src/views/Editor/index.js b/apps/mobile/src/views/Editor/index.js index e81323439..fec9173f2 100755 --- a/apps/mobile/src/views/Editor/index.js +++ b/apps/mobile/src/views/Editor/index.js @@ -1,6 +1,5 @@ -import React, {useEffect, useState} from 'react'; +import React, {createRef, useEffect, useState} from 'react'; import { - ActivityIndicator, BackHandler, KeyboardAvoidingView, Linking, @@ -9,16 +8,15 @@ import { Text, TouchableOpacity, View, + SafeAreaView, } from 'react-native'; -import * as Animatable from 'react-native-animatable'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import WebView from 'react-native-webview'; import {db, DDS} from '../../../App'; -import {SIZE, WEIGHT, normalize, opacity} from '../../common/common'; +import {normalize, SIZE, WEIGHT} from '../../common/common'; import { ActionSheetEvent, simpleDialogEvent, - TEMPLATE_EXIT, TEMPLATE_EXIT_FULLSCREEN, TEMPLATE_INFO, } from '../../components/DialogManager'; @@ -34,19 +32,17 @@ import { eOnLoadNote, eOpenFullscreenEditor, } from '../../services/events'; +import {exitEditorAnimation} from '../../utils/animations'; import { + editing, SideMenuEvent, timeConverter, ToastEvent, - editing, } from '../../utils/utils'; -import {AnimatedSafeAreaView} from '../Home'; -import NavigationService from '../../services/NavigationService'; -let EditorWebView; +const EditorWebView = createRef(); let note = {}; let id = null; -let dateEdited = null; var content = null; var title = null; let timer = null; @@ -57,12 +53,18 @@ const Editor = ({navigation, noMenu}) => { // Global State const [state, dispatch] = useTracked(); const {colors} = state; - const [loading, setLoading] = useState(true); const [fullscreen, setFullscreen] = useState(false); - + const [dateEdited, setDateEdited] = useState(0); // FUNCTIONS - const post = value => EditorWebView.postMessage(value); + const post = value => EditorWebView.current?.postMessage(value); + + useEffect(() => { + let c = {...colors}; + c.factor = normalize(1); + post(JSON.stringify(c)); + }, [colors.bg]); + useEffect(() => { eSubscribeEvent(eOnLoadNote, loadNote); @@ -71,56 +73,44 @@ const Editor = ({navigation, noMenu}) => { }; }, []); - useEffect(() => { - setLoading(true); - setTimeout(() => { - setLoading(false); - }, 3000); - }, [colors.bg]); - - const loadNote = item => { + const loadNote = async item => { if (note && note.id) { - saveNote(true).then(() => { - dispatch({type: ACTIONS.NOTES}); - if (item && item.type === 'new') { - clearEditor(); - } else { - note = item; - if (DDS.isTab) { - dispatch({ - type: ACTIONS.CURRENT_EDITING_NOTE, - id: item.id, - }); - } - - updateEditor(); - } - }); + dispatch({type: ACTIONS.NOTES}); + if (item && item.type === 'new') { + await clearEditor(); + } else { + note = item; + dispatch({ + type: ACTIONS.CURRENT_EDITING_NOTE, + id: item.id, + }); + updateEditor(); + } } else { dispatch({type: ACTIONS.NOTES}); if (item && item.type === 'new') { - clearEditor(); + await clearEditor(); } else { note = item; - if (DDS.isTab) { - dispatch({ - type: ACTIONS.CURRENT_EDITING_NOTE, - id: item.id, - }); - } + dispatch({ + type: ACTIONS.CURRENT_EDITING_NOTE, + id: item.id, + }); updateEditor(); } } }; - const clearEditor = () => { - id = null; + const clearEditor = async () => { + await saveNote(); title = null; content = null; - note = {}; + note = null; + id = null; + tapCount = 0; saveCounter = 0; - EditorWebView.reload(); - + post('clear'); + post(JSON.stringify({type: 'text', value: ''})); post('focusTitle'); }; @@ -137,7 +127,6 @@ const Editor = ({navigation, noMenu}) => { const _onMessage = evt => { if (evt.nativeEvent.data === 'loaded') { - setLoading(false); } else if ( evt.nativeEvent.data !== '' && evt.nativeEvent.data !== 'loaded' @@ -171,8 +160,6 @@ const Editor = ({navigation, noMenu}) => { }; } - console.log(content.delta, 'i am called'); - let rId = await db.notes.add({ title, content: { @@ -195,8 +182,7 @@ const Editor = ({navigation, noMenu}) => { } }, 500); } - - if (DDS.isTab) { + if (id) { dispatch({ type: ACTIONS.CURRENT_EDITING_NOTE, id: id, @@ -254,17 +240,10 @@ const Editor = ({navigation, noMenu}) => { ); } - if (navigation && navigation.state.params && navigation.state.params.note) { - note = navigation.state.params.note; - - updateEditor(); - } else if (note && note.id) { + if (note && note.id) { updateEditor(); } else { post('focusTitle'); - wait(500).then(() => { - setLoading(false); - }); } let c = {...colors}; c.factor = normalize(1); @@ -280,17 +259,14 @@ const Editor = ({navigation, noMenu}) => { }); const updateEditor = async () => { - console.log('before', content, title, id); title = note.title; id = note.id; - dateEdited = note.dateEdited; + setDateEdited(note.dateEdited); content = note.content; if (!note.locked) { content.delta = await db.notes.note(id).delta(); } - console.log('after', content, title, id); - saveCounter = 0; if (title !== null || title === '') { @@ -303,18 +279,11 @@ const Editor = ({navigation, noMenu}) => { } else { post('focusTitle'); post('clear'); - wait(500).then(() => { - setLoading(false); - }); } if (note.content.text === '' && note.content.delta === null) { post('clear'); - wait(500).then(() => { - setLoading(false); - }); } else if (note.content.delta) { let delta; - console.log(note.content.delta, 'HERE'); if (typeof note.content.delta !== 'string') { delta = note.content.delta; } else { @@ -324,9 +293,6 @@ const Editor = ({navigation, noMenu}) => { post(JSON.stringify(delta)); } else { post(JSON.stringify({type: 'text', value: note.content.text})); - wait(2000).then(() => { - setLoading(false); - }); } }; @@ -340,8 +306,92 @@ const Editor = ({navigation, noMenu}) => { link.click(); }`; - const _renderEditor = () => { - return ( + const closeFullscreen = () => { + setFullscreen(false); + }; + + // EFFECTS + + useEffect(() => { + eSubscribeEvent(eCloseFullscreenEditor, closeFullscreen); + + return () => { + eUnSubscribeEvent(eCloseFullscreenEditor, closeFullscreen); + }; + }); + + const _onHardwareBackPress = async () => { + if (tapCount > 0) { + exitEditorAnimation(); + await clearEditor(); + ToastEvent.show('Note Saved!', 'success'); + return true; + } else { + tapCount = 1; + setTimeout(() => { + tapCount = 0; + }, 3000); + ToastEvent.show('Press back again to exit editor', 'success'); + return true; + } + }; + + useEffect(() => { + editing.currentlyEditing = true; + + let handleBack; + if (!noMenu && DDS.isTab) { + handleBack = BackHandler.addEventListener('hardwareBackPress', () => { + simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN()); + editing.isFullscreen = false; + return true; + }); + } else if (!DDS.isTab) { + handleBack = BackHandler.addEventListener( + 'hardwareBackPress', + _onHardwareBackPress, + ); + } else { + if (handleBack) { + handleBack.remove(); + handleBack = null; + } + } + + return () => { + editing.currentlyEditing = false; + if (handleBack) { + handleBack.remove(); + handleBack = null; + } + title = null; + content = null; + id = null; + timer = null; + note = {}; + }; + }, [noMenu]); + + useEffect(() => { + noMenu ? null : SideMenuEvent.disable(); + + return () => { + if (noMenu) return; + DDS.isTab ? SideMenuEvent.open() : null; + SideMenuEvent.enable(); + }; + }); + + return ( + { if (DDS.isTab) { simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN()); } else { - await closeEditor(); + exitEditorAnimation(); + await clearEditor(); + ToastEvent.show('Note Saved!', 'success'); } }} style={{ @@ -469,7 +521,7 @@ const Editor = ({navigation, noMenu}) => { (EditorWebView = ref)} + ref={EditorWebView} onError={error => console.log(error)} onLoad={onWebViewLoad} javaScriptEnabled={true} @@ -511,149 +563,7 @@ const Editor = ({navigation, noMenu}) => { onMessage={_onMessage} /> - ); - }; - - const closeFullscreen = () => { - setFullscreen(false); - }; - - // EFFECTS - - useEffect(() => { - eSubscribeEvent(eCloseFullscreenEditor, closeFullscreen); - - return () => { - eUnSubscribeEvent(eCloseFullscreenEditor, closeFullscreen); - }; - }); - - const closeEditor = async () => { - await saveNote(); - title = null; - content = null; - note = null; - id = null; - dateEdited = null; - tapCount = 0; - NavigationService.goBack(); - ToastEvent.show('Note Saved!', 'success'); - }; - - const _onHardwareBackPress = async () => { - if (tapCount > 0) { - await closeEditor(); - - return true; - } else { - tapCount = 1; - setTimeout(() => { - tapCount = 0; - }, 3000); - ToastEvent.show('Press back again to exit editor', 'success'); - return true; - } - }; - - useEffect(() => { - editing.currentlyEditing = true; - - let handleBack; - if (!noMenu && DDS.isTab) { - handleBack = BackHandler.addEventListener('hardwareBackPress', () => { - simpleDialogEvent(TEMPLATE_EXIT_FULLSCREEN()); - editing.isFullscreen = false; - return true; - }); - } else if (!DDS.isTab) { - handleBack = BackHandler.addEventListener( - 'hardwareBackPress', - _onHardwareBackPress, - ); - } else { - if (handleBack) { - handleBack.remove(); - handleBack = null; - } - } - - return () => { - editing.currentlyEditing = false; - if (handleBack) { - handleBack.remove(); - handleBack = null; - } - title = null; - content = null; - id = null; - timer = null; - note = {}; - }; - }, [noMenu]); - - useEffect(() => { - noMenu ? null : SideMenuEvent.disable(); - - return () => { - if (noMenu) return; - DDS.isTab ? SideMenuEvent.open() : null; - SideMenuEvent.enable(); - }; - }); - - useEffect(() => { - EditorWebView.reload(); - }, [colors]); - - return ( - - - - - - Write with confidence. - - - - - {_renderEditor()} - - + ); };