diff --git a/apps/mobile/src/components/SimpleList/index.js b/apps/mobile/src/components/SimpleList/index.js index 87ceaf3ba..efa8b2d9b 100644 --- a/apps/mobile/src/components/SimpleList/index.js +++ b/apps/mobile/src/components/SimpleList/index.js @@ -1,388 +1,389 @@ import React, {useCallback, useEffect, useMemo, useState} from 'react'; -import {Platform, RefreshControl, StyleSheet, Text, useWindowDimensions, View} from 'react-native'; +import { + Platform, + RefreshControl, + StyleSheet, + Text, + useWindowDimensions, + View, +} from 'react-native'; import {initialWindowMetrics} from 'react-native-safe-area-context'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; import {DataProvider, LayoutProvider, RecyclerListView} from 'recyclerlistview'; import {useTracked} from '../../provider'; import {Actions} from '../../provider/Actions'; import {eSendEvent, ToastEvent} from '../../services/EventManager'; -import {eClearSearch, eOpenLoginDialog, eScrollEvent,} from '../../utils/Events'; +import {eClearSearch, eOpenLoginDialog, eScrollEvent} from '../../utils/Events'; import {PressableButton} from '../PressableButton'; -import {COLORS_NOTE} from "../../utils/Colors"; -import {SIZE, WEIGHT} from "../../utils/SizeUtils"; -import {db} from "../../utils/DB"; +import {COLORS_NOTE} from '../../utils/Colors'; +import {SIZE, WEIGHT} from '../../utils/SizeUtils'; +import {db} from '../../utils/DB'; const header = { - type: 'MAIN_HEADER', + type: 'MAIN_HEADER', }; const SimpleList = ({ - data, - type, - placeholder, - RenderItem, - focused, - customRefresh, - customRefreshing, - refreshCallback, - }) => { - const [state, dispatch] = useTracked(); - const {colors, selectionMode, user} = state; - const searchResults = {...state.searchResults}; - const [refreshing, setRefreshing] = useState(false); - const [dataProvider, setDataProvider] = useState( - new DataProvider((r1, r2) => { - return r1 !== r2; - }), - ); - const {width, fontScale} = useWindowDimensions(); + data, + type, + placeholder, + RenderItem, + focused, + customRefresh, + customRefreshing, + refreshCallback, +}) => { + const [state, dispatch] = useTracked(); + const {colors, selectionMode, user, messageBoardState} = state; + const searchResults = {...state.searchResults}; + const [refreshing, setRefreshing] = useState(false); + const [dataProvider, setDataProvider] = useState( + new DataProvider((r1, r2) => { + return r1 !== r2; + }), + ); + const {width, fontScale} = useWindowDimensions(); - const listData = data; - const dataType = type; - const _onScroll = (event) => { - if (!event) return; - let y = event.nativeEvent.contentOffset.y; - eSendEvent(eScrollEvent, y); - }; + const listData = data; + const dataType = type; + const _onScroll = (event) => { + if (!event) return; + let y = event.nativeEvent.contentOffset.y; + eSendEvent(eScrollEvent, y); + }; - useEffect(() => { - loadData(); - }, [listData]); + useEffect(() => { + loadData(); + }, [listData]); - const loadData =() => { - let mainData = - searchResults.type === type && - focused() && - searchResults.results.length > 0 - ? searchResults.results - : listData; + const loadData = () => { + let mainData = + searchResults.type === type && + focused() && + searchResults.results.length > 0 + ? searchResults.results + : listData; - let d = [header, ...mainData]; - setDataProvider( - dataProvider.cloneWithRows(d), - ); + let d = [header, ...mainData]; + setDataProvider(dataProvider.cloneWithRows(d)); + }; + + const RenderSectionHeader = ({item}) => ( + + {item.title} + + ); + + const _onRefresh = useCallback(async () => { + if (Platform.OS === 'ios') { + dispatch({ + type: Actions.SYNCING, + syncing: true, + }); + } else { + setRefreshing(true); } - - const RenderSectionHeader = ({item}) => ( - - {item.title} - - ); - - const _onRefresh = useCallback(async () => { - if (Platform.OS === 'ios') { - dispatch({ - type: Actions.SYNCING, - syncing: true, - }); - } else { - setRefreshing(true); - } - try { - let user = await db.user.get(); - dispatch({type: Actions.USER, user: user}); - await db.sync(); - ToastEvent.show('Sync Complete', 'success'); - } catch (e) { - ToastEvent.show( - "You must login to sync.", - 'error', - 'global', - 5000, - () => { - eSendEvent(eOpenLoginDialog); - }, - 'Login', - ); - } finally { - if (Platform.OS === 'ios') { - dispatch({ - type: Actions.SYNCING, - syncing: false, - }); - } else { - setRefreshing(false); - } - if (refreshCallback) { - refreshCallback(); - } - } - dispatch({type: Actions.ALL}); - - }, []); - - const _ListEmptyComponent = ( - - <>{placeholder} - - ); - - const _layoutProvider = new LayoutProvider( - (index) => { - return dataProvider.getDataForIndex(index).type; + try { + let user = await db.user.get(); + dispatch({type: Actions.USER, user: user}); + await db.sync(); + ToastEvent.show('Sync Complete', 'success'); + } catch (e) { + ToastEvent.show( + 'You must login to sync.', + 'error', + 'global', + 5000, + () => { + eSendEvent(eOpenLoginDialog); }, - (type, dim) => { + 'Login', + ); + } finally { + if (Platform.OS === 'ios') { + dispatch({ + type: Actions.SYNCING, + syncing: false, + }); + } else { + setRefreshing(false); + } + if (refreshCallback) { + refreshCallback(); + } + } + dispatch({type: Actions.ALL}); + }, []); - switch (type) { - case 'note': - dim.width = width; - dim.height = 100 * fontScale; - break; - case 'notebook': - dim.width = width; - dim.height = 110 * fontScale; - break; - case 'topic': - dim.width = width; - dim.height = 80 * fontScale; - break; - case 'tag': - dim.width = width; - dim.height = 80 * fontScale; - break; - case 'header': - dim.width = width; - dim.height = 30 * fontScale; - break; - case 'MAIN_HEADER': - dim.width = width; - dim.height = - (user && user.Id) || !listData[0] || selectionMode - ? 0 - : 40 * fontScale; - break; - default: - dim.width = width; - dim.height = 0; - } + const _ListEmptyComponent = ( + + <>{placeholder} + + ); - const _renderRow = (type, data, index) => { - switch (type) { - case 'note': - return ; - case 'notebook': - return ; - case 'MAIN_HEADER': - return ; - case 'header': - return ; - default: - return ; - } + const _layoutProvider = new LayoutProvider( + (index) => { + return dataProvider.getDataForIndex(index).type; + }, + (type, dim) => { + switch (type) { + case 'note': + dim.width = width; + dim.height = 100 * fontScale; + break; + case 'notebook': + dim.width = width; + dim.height = 110 * fontScale; + break; + case 'topic': + dim.width = width; + dim.height = 80 * fontScale; + break; + case 'tag': + dim.width = width; + dim.height = 80 * fontScale; + break; + case 'header': + dim.width = width; + dim.height = 30 * fontScale; + break; + case 'MAIN_HEADER': + dim.width = width; + dim.height = + !messageBoardState.visible || !listData[0] || selectionMode + ? 0 + : 40 * fontScale; + break; + default: + dim.width = width; + dim.height = 0; + } + }, + ); + + const _renderRow = (type, data, index) => { + switch (type) { + case 'note': + return ; + case 'notebook': + return ; + case 'MAIN_HEADER': + return ; + case 'header': + return ; + default: + return ; + } + }; + + const listStyle = useMemo(() => { + return { + height: '100%', + backgroundColor: colors.bg, + width: '100%', + paddingTop: + Platform.OS === 'ios' + ? listData[0] && !selectionMode + ? 130 + : 130 - 60 + : listData[0] && !selectionMode + ? 150 - initialWindowMetrics.insets.top + : (150 - initialWindowMetrics.insets.top) - 60, }; + }, [selectionMode, listData, colors]); - const listStyle = useMemo(() => { - return { - height: '100%', - backgroundColor: colors.bg, - width: '100%', - paddingTop: - Platform.OS === 'ios' - ? listData[0] && !selectionMode - ? 130 - : 130 - 60 - : listData[0] && !selectionMode - ? 155 - initialWindowMetrics.insets.top - : 155 - initialWindowMetrics.insets.top - 60, - }; - }, [selectionMode, listData, colors]); - - return !listData || listData.length === 0 || !dataProvider ? ( - _ListEmptyComponent - ) : ( - } - scrollViewProps={{ - refreshControl: ( - - ), - contentContainerStyle: { - width: '100%', - alignSelf: 'center', - minHeight: '100%', - }, - }} - style={listStyle} - /> - ); + return !listData || listData.length === 0 || !dataProvider ? ( + _ListEmptyComponent + ) : ( + } + scrollViewProps={{ + refreshControl: ( + + ), + contentContainerStyle: { + width: '100%', + alignSelf: 'center', + minHeight: '100%', + }, + }} + style={listStyle} + /> + ); }; export default SimpleList; const SearchHeader = () => { - const [state,] = useTracked(); - const {colors} = state; - const searchResults = {...state.searchResults}; + const [state] = useTracked(); + const {colors} = state; + const searchResults = {...state.searchResults}; - return ( - - - Showing Results for {searchResults.keyword} - - { - eSendEvent(eClearSearch); - }} - style={{ - fontFamily: WEIGHT.regular, - color: colors.errorText, - fontSize: SIZE.xs, - }}> - Clear - - - ); + return ( + + + Showing Results for {searchResults.keyword} + + { + eSendEvent(eClearSearch); + }} + style={{ + fontFamily: WEIGHT.regular, + color: colors.errorText, + fontSize: SIZE.xs, + }}> + Clear + + + ); }; -const LoginCard = ({type, data}) => { - const [state,] = useTracked(); - const {colors, selectionMode, user, currentScreen} = state; +const MessageCard = ({data}) => { + const [state] = useTracked(); + const {colors, selectionMode, currentScreen, messageBoardState} = state; - return ( - - {(user && user.Id) || !data[0] || selectionMode ? null : ( - { - eSendEvent(eOpenLoginDialog); - }} - color={ - COLORS_NOTE[currentScreen] - ? COLORS_NOTE[currentScreen] - : colors.shade - } - selectedColor={ - COLORS_NOTE[currentScreen] - ? COLORS_NOTE[currentScreen] - : colors.accent - } - alpha={!colors.night ? -0.02 : 0.1} - opacity={0.12} - customStyle={styles.loginCard}> - - - - - - You are not logged in - - - Login to sync your {type}. - - - - )} - - ); + return ( + + {!messageBoardState.visible || !data[0] || selectionMode ? null : ( + + + + + + + {messageBoardState.message} + + + {messageBoardState.data.actionText} + + + + )} + + ); }; const ListHeaderComponent = ({type, data}) => { - const [state,] = useTracked(); - const searchResults = {...state.searchResults}; + const [state] = useTracked(); + const searchResults = {...state.searchResults}; - return searchResults.type === type && searchResults.results.length > 0 ? ( - - ) : ( - - ); + return searchResults.type === type && searchResults.results.length > 0 ? ( + + ) : ( + + ); }; const styles = StyleSheet.create({ - loginCard: { - width: '100%', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-start', - paddingHorizontal: 12, - alignSelf: 'center', - height: 40, - borderRadius: 0, - position: 'relative', - }, - loginIcon: { - textAlign: 'center', - textAlignVertical: 'center', - }, - searchHeader: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - paddingHorizontal: 12, - height: 40, - }, - sectionHeader: { - fontFamily: WEIGHT.bold, - fontSize: SIZE.xs + 1, - paddingHorizontal: 12, - width: '100%', - alignSelf: 'center', - marginTop: 10, - height: 25, - textAlignVertical: 'center', - }, - emptyList: { - height: '100%', - width: '100%', - alignItems: 'center', - alignSelf: 'center', - justifyContent: 'center', - opacity: 1, - }, + loginCard: { + width: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + paddingHorizontal: 12, + alignSelf: 'center', + height: 40, + borderRadius: 0, + position: 'relative', + }, + loginIcon: { + textAlign: 'center', + textAlignVertical: 'center', + }, + searchHeader: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 12, + height: 40, + }, + sectionHeader: { + fontFamily: WEIGHT.bold, + fontSize: SIZE.xs + 1, + paddingHorizontal: 12, + width: '100%', + alignSelf: 'center', + marginTop: 10, + height: 25, + textAlignVertical: 'center', + }, + emptyList: { + height: '100%', + width: '100%', + alignItems: 'center', + alignSelf: 'center', + justifyContent: 'center', + opacity: 1, + }, }); diff --git a/apps/mobile/src/provider/DefaultState.js b/apps/mobile/src/provider/DefaultState.js index e5a6c4bba..3b3eb8c8b 100644 --- a/apps/mobile/src/provider/DefaultState.js +++ b/apps/mobile/src/provider/DefaultState.js @@ -73,5 +73,13 @@ export const defaultState = { bottomButtonOnPress: () => {}, bottomButtonText: 'Create a new note', }, + messageBoardState: { + visible:false, + message:null, + actionText:null, + onPress:() => {}, + data:{}, + icon:'account-outline' + }, keyword: [], }; diff --git a/apps/mobile/src/services/Backup.js b/apps/mobile/src/services/Backup.js index 2bcc49f49..6fbdca8ca 100644 --- a/apps/mobile/src/services/Backup.js +++ b/apps/mobile/src/services/Backup.js @@ -24,7 +24,7 @@ async function run() { await MMKV.setItem('backupDate', JSON.stringify(Date.now())); ToastEvent.show('Backup complete!', 'success'); return path; -} +} async function getLastBackupDate() { let date; diff --git a/apps/mobile/src/utils/index.js b/apps/mobile/src/utils/index.js index 4add1ba1e..53a376fb3 100755 --- a/apps/mobile/src/utils/index.js +++ b/apps/mobile/src/utils/index.js @@ -9,7 +9,6 @@ export async function setSetting(settings, name, value) { let s = {...settings}; s[name] = value; await MMKV.setStringAsync('settings', JSON.stringify(s)); - updateEvent({type: Actions.SETTINGS, settings: s}); } @@ -17,7 +16,6 @@ export const dirs = RNFetchBlob.fs.dirs; export const ANDROID_PATH = dirs.SDCardDir + '/Notesnook/'; export const IOS_PATH = dirs.DocumentDir; - export const getElevation = (elevation) => { return { elevation, @@ -45,8 +43,6 @@ export const history = { selectedItemsList: [], }; - - export async function showContext(event, title) { eSendEvent('showContextMenu', { location: { diff --git a/apps/mobile/src/views/Editor/Functions.js b/apps/mobile/src/views/Editor/Functions.js index 90c13f1da..2b182ccaf 100644 --- a/apps/mobile/src/views/Editor/Functions.js +++ b/apps/mobile/src/views/Editor/Functions.js @@ -261,7 +261,7 @@ export async function saveNote(caller) { }, id: id, }); - if (!id) { + if (!id || saveCounter < 3) { updateEvent({ type: Actions.NOTES, }); diff --git a/apps/mobile/src/views/Notebook/index.js b/apps/mobile/src/views/Notebook/index.js index 835de0487..a9c2df05e 100644 --- a/apps/mobile/src/views/Notebook/index.js +++ b/apps/mobile/src/views/Notebook/index.js @@ -39,9 +39,8 @@ export const Notebook = ({route, navigation}) => { }; }, []); - const onFocus = useCallback(() => { + const onFocus = () => { onLoad(); - dispatch({ type: Actions.HEADER_TEXT_STATE, state: { @@ -61,7 +60,7 @@ export const Notebook = ({route, navigation}) => { type: Actions.CURRENT_SCREEN, screen: 'notebook', }); - }, []); + } useEffect(() => { navigation.addListener('focus', onFocus); diff --git a/apps/mobile/src/views/Notes/index.js b/apps/mobile/src/views/Notes/index.js index 1f4ed6a57..31f90d168 100644 --- a/apps/mobile/src/views/Notes/index.js +++ b/apps/mobile/src/views/Notes/index.js @@ -55,6 +55,7 @@ export const Notes = ({route, navigation}) => { }, []); const init = (data) => { + console.log('refreshing notes!'); params = route.params; if (data) { params = data;