diff --git a/apps/mobile/App.js b/apps/mobile/App.js index c4f5abf53..d81fc11c6 100644 --- a/apps/mobile/App.js +++ b/apps/mobile/App.js @@ -1,33 +1,37 @@ import * as NetInfo from '@react-native-community/netinfo'; -import { CHECK_IDS, EV } from 'notes-core/common'; -import React, { useEffect, useState } from 'react'; +import {CHECK_IDS, EV} from 'notes-core/common'; +import React, {useEffect, useState} from 'react'; import { Appearance, AppState, Linking, NativeModules, Platform, - StatusBar + StatusBar, } from 'react-native'; import * as RNIap from 'react-native-iap'; -import { enabled } from 'react-native-privacy-snapshot'; -import { SafeAreaProvider } from 'react-native-safe-area-context'; +import {enabled} from 'react-native-privacy-snapshot'; +import {SafeAreaProvider} from 'react-native-safe-area-context'; import SplashScreen from 'react-native-splash-screen'; -import { useTracked } from './src/provider'; -import { Actions } from './src/provider/Actions'; -import { DDS } from './src/services/DeviceDetection'; +import {useTracked} from './src/provider'; +import {Actions} from './src/provider/Actions'; +import {DDS} from './src/services/DeviceDetection'; import { eSendEvent, eSubscribeEvent, - eUnSubscribeEvent + eUnSubscribeEvent, } from './src/services/EventManager'; import IntentService from './src/services/IntentService'; -import { clearMessage, setLoginMessage } from './src/services/Message'; +import { + clearMessage, + setEmailVerifyMessage, + setLoginMessage, +} from './src/services/Message'; import Navigation from './src/services/Navigation'; import PremiumService from './src/services/PremiumService'; -import { editing } from './src/utils'; -import { COLOR_SCHEME } from './src/utils/Colors'; -import { db } from './src/utils/DB'; +import {editing} from './src/utils'; +import {COLOR_SCHEME} from './src/utils/Colors'; +import {db} from './src/utils/DB'; import { eClosePremiumDialog, eDispatchAction, @@ -36,12 +40,12 @@ import { eOpenPremiumDialog, eOpenSideMenu, eShowGetPremium, - eStartSyncer + eStartSyncer, } from './src/utils/Events'; -import { MMKV } from './src/utils/mmkv'; -import { tabBarRef } from './src/utils/Refs'; -import { sleep } from './src/utils/TimeUtils'; -import { getNote } from './src/views/Editor/Functions'; +import {MMKV} from './src/utils/mmkv'; +import {tabBarRef} from './src/utils/Refs'; +import {sleep} from './src/utils/TimeUtils'; +import {getNote} from './src/views/Editor/Functions'; const {ReceiveSharingIntent} = NativeModules; let AppRootView = require('./initializer.root').RootView; @@ -134,7 +138,7 @@ const App = () => { }; const startSyncer = async () => { try { - let user = await db.user.get(); + let user = await db.user.getUser(); if (user) { EV.subscribe('db:refresh', syncChanges); } @@ -152,18 +156,24 @@ const App = () => { let url = res ? res.url : ''; try { - if (url.startsWith('ShareMedia://dataUrl')) { - console.log(url); + if (Platform.OS === 'ios' && url.startsWith('ShareMedia://dataUrl')) { _data = await ReceiveSharingIntent.getFileNames(url); _data = IntentService.iosSortedData(_data); - } - if (_data) { - IntentService.setIntent(_data); - IntentService.check((event) => { - eSendEvent(eOnLoadNote, event); - tabBarRef.current?.goToPage(1); - Navigation.closeDrawer(); - }); + + if (_data) { + IntentService.setIntent(_data); + IntentService.check((event) => { + eSendEvent(eOnLoadNote, event); + tabBarRef.current?.goToPage(1); + Navigation.closeDrawer(); + }); + } + } else if (url.startsWith('https://notesnook.com/verify')) { + let user = await db.user.fetchUser(); + dispatch({type: Actions.USER, user: user}); + if (user.isEmailConfirmed) { + clearMessage(dispatch); + } } } catch (e) { console.log(e, 'ERROR HERE'); @@ -252,6 +262,7 @@ const App = () => { try { dispatch({type: Actions.SYNCING, syncing: true}); await db.sync(false); + dispatch({type: Actions.LAST_SYNC, lastSync: await db.lastSynced()}); } catch (e) { } finally { dispatch({type: Actions.SYNCING, syncing: false}); @@ -270,9 +281,7 @@ const App = () => { eSubscribeEvent('nointent', loadMainApp); Appearance.addChangeListener(onSystemThemeChanged); let unsub = NetInfo.addEventListener(onNetworkStateChanged); - if (Platform.OS === 'ios') { - Linking.addEventListener('url', _handleIntent); - } + Linking.addEventListener('url', _handleIntent); EV.subscribe('db:sync', dbSync); EV.subscribe('user:checkStatus', handlePremiumAccess); return () => { @@ -285,9 +294,7 @@ const App = () => { eUnSubscribeEvent('nointent', loadMainApp); AppState.removeEventListener('change', onAppStateChanged); Appearance.removeChangeListener(onSystemThemeChanged); - if (Platform.OS === 'ios') { - Linking.removeEventListener('url', _handleIntent); - } + Linking.removeEventListener('url', _handleIntent); unsub(); unsubIAP(); }; @@ -326,14 +333,19 @@ const App = () => { const getUser = async () => { try { - let user = await db.user.get(); + let user = await db.user.fetchUser(); if (user) { + clearMessage(dispatch); + if (!user.isEmailConfirmed) { + setEmailVerifyMessage(dispatch); + } dispatch({type: Actions.SYNCING, syncing: true}); dispatch({type: Actions.USER, user: user}); await db.sync(); + dispatch({type: Actions.LAST_SYNC, lastSync: await db.lastSynced()}); dispatch({type: Actions.ALL}); await startSyncer(); - clearMessage(dispatch); + } else { setLoginMessage(dispatch); } diff --git a/apps/mobile/android/app/src/main/AndroidManifest.xml b/apps/mobile/android/app/src/main/AndroidManifest.xml index ec065e6c5..58a7d5e83 100644 --- a/apps/mobile/android/app/src/main/AndroidManifest.xml +++ b/apps/mobile/android/app/src/main/AndroidManifest.xml @@ -27,9 +27,18 @@ android:windowSoftInputMode="adjustResize"> - + + + + + + + + - - - - diff --git a/apps/mobile/src/components/ActionSheetComponent/index.js b/apps/mobile/src/components/ActionSheetComponent/index.js index 49d5c054d..3847184b4 100644 --- a/apps/mobile/src/components/ActionSheetComponent/index.js +++ b/apps/mobile/src/components/ActionSheetComponent/index.js @@ -475,8 +475,7 @@ export const ActionSheetComponent = ({ ToastEvent.show(e.message, 'error', 'local', 5000); } } finally { - let user = await db.user.get(); - dispatch({type: Actions.USER, user: user}); + dispatch({type: Actions.LAST_SYNC,lastSync: await db.lastSynced()}); dispatch({type: Actions.ALL}); setRefreshing(false); } diff --git a/apps/mobile/src/components/Header/index.js b/apps/mobile/src/components/Header/index.js index 6341a679b..ccec6efa4 100644 --- a/apps/mobile/src/components/Header/index.js +++ b/apps/mobile/src/components/Header/index.js @@ -1,19 +1,18 @@ -import React, {useEffect, useState} from 'react'; -import {Platform, StyleSheet, View} from 'react-native'; -import Animated from 'react-native-reanimated'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import {useTracked} from '../../provider'; -import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager'; +import React, { useEffect, useState } from 'react'; +import { Platform, StyleSheet, View } from 'react-native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { useTracked } from '../../provider'; +import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager'; import Navigation from '../../services/Navigation'; +import { dWidth } from '../../utils'; +import { eScrollEvent } from '../../utils/Events'; +import { SIZE } from '../../utils/SizeUtils'; +import { ActionIcon } from '../ActionIcon'; +import { SearchInput } from '../SearchInput'; +import { HeaderLeftMenu } from './HeaderLeftMenu'; +import { HeaderRightMenu } from './HeaderRightMenu'; +import { HeaderTitle } from './HeaderTitle'; -import {dWidth} from '../../utils'; -import {eScrollEvent} from '../../utils/Events'; -import {SIZE} from '../../utils/SizeUtils'; -import {ActionIcon} from '../ActionIcon'; -import {SearchInput} from '../SearchInput'; -import {HeaderLeftMenu} from './HeaderLeftMenu'; -import {HeaderRightMenu} from './HeaderRightMenu'; -import {HeaderTitle} from './HeaderTitle'; export const Header = ({root}) => { const [state] = useTracked(); diff --git a/apps/mobile/src/components/LoginDialog/index.js b/apps/mobile/src/components/LoginDialog/index.js index 2f9ebd806..048b50b55 100644 --- a/apps/mobile/src/components/LoginDialog/index.js +++ b/apps/mobile/src/components/LoginDialog/index.js @@ -188,11 +188,12 @@ const LoginDialog = () => { } try { - let user = await db.user.get(); + let user = await db.user.getUser() if (!user) throw new Error('Email or passoword incorrect!'); setStatus('Syncing Data'); dispatch({type: Actions.USER, user: user}); await db.sync(); + dispatch({type: Actions.LAST_SYNC,lastSync: await db.lastSynced()}); eSendEvent(eStartSyncer); dispatch({type: Actions.ALL}); eSendEvent(refreshNotesPage); @@ -257,9 +258,10 @@ const LoginDialog = () => { let user; try { - user = await db.user.get(); + user = await db.user.getUser() setStatus('Setting up crenditials'); dispatch({type: Actions.USER, user: user}); + dispatch({type: Actions.LAST_SYNC,lastSync: await db.lastSynced()}); eSendEvent(eStartSyncer); clearMessage(dispatch); close(); diff --git a/apps/mobile/src/components/Menu/UserSection.js b/apps/mobile/src/components/Menu/UserSection.js index 9ee56be44..34515f6f9 100644 --- a/apps/mobile/src/components/Menu/UserSection.js +++ b/apps/mobile/src/components/Menu/UserSection.js @@ -57,8 +57,7 @@ export const UserSection = ({noTextMode}) => { } catch (e) { ToastEvent.show(e.message, 'error'); } finally { - let user = await db.user.get(); - dispatch({type: Actions.USER, user: user}); + dispatch({type: Actions.LAST_SYNC,lastSync: await db.lastSynced()}); dispatch({type: Actions.ALL}); dispatch({ type: Actions.SYNCING, diff --git a/apps/mobile/src/components/Premium/PendingDialog.js b/apps/mobile/src/components/Premium/PendingDialog.js index c977e6303..c76c45149 100644 --- a/apps/mobile/src/components/Premium/PendingDialog.js +++ b/apps/mobile/src/components/Premium/PendingDialog.js @@ -24,7 +24,7 @@ class PendingDialog extends React.Component { async open() { actionSheet.current?._setModalVisible(true); - let u = await db.user.get(); + let u = await db.user.fetchUser(); this.setState({ user: u && u.Id ? u : null, }); diff --git a/apps/mobile/src/components/Premium/PremiumDialog.js b/apps/mobile/src/components/Premium/PremiumDialog.js index 1b3d85a0f..a8b80b272 100644 --- a/apps/mobile/src/components/Premium/PremiumDialog.js +++ b/apps/mobile/src/components/Premium/PremiumDialog.js @@ -48,7 +48,7 @@ class PremiumDialog extends React.Component { async getSkus() { try { - let u = await db.user.get(); + let u = await db.user.getUser() this.setState({ user: u, }); diff --git a/apps/mobile/src/components/RecoveryKeyDialog/index.js b/apps/mobile/src/components/RecoveryKeyDialog/index.js index 690fe2992..2c9aa4866 100644 --- a/apps/mobile/src/components/RecoveryKeyDialog/index.js +++ b/apps/mobile/src/components/RecoveryKeyDialog/index.js @@ -126,7 +126,7 @@ class RecoveryKeyDialog extends React.Component { onOpen = async () => { let k = await db.user.key(); - this.user = await db.user.get(); + this.user = await db.user.getUser(); if (k) { this.setState({ diff --git a/apps/mobile/src/components/SelectionHeader/index.js b/apps/mobile/src/components/SelectionHeader/index.js index b1e77753a..5d959ee8b 100644 --- a/apps/mobile/src/components/SelectionHeader/index.js +++ b/apps/mobile/src/components/SelectionHeader/index.js @@ -1,21 +1,20 @@ -import React, {useEffect} from 'react'; -import {TouchableOpacity, View} from 'react-native'; -import Animated, {Easing, useValue} from 'react-native-reanimated'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; -import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; -import {useTracked} from '../../provider'; -import {Actions} from '../../provider/Actions'; -import {eSendEvent, ToastEvent} from '../../services/EventManager'; -import {db} from '../../utils/DB'; +import React, { useEffect } from 'react'; +import { View } from 'react-native'; +import Animated, { Easing, useValue } from 'react-native-reanimated'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { useTracked } from '../../provider'; +import { Actions } from '../../provider/Actions'; +import { eSendEvent, ToastEvent } from '../../services/EventManager'; +import { db } from '../../utils/DB'; import { eOpenMoveNoteDialog, eOpenSimpleDialog, - refreshNotesPage, + refreshNotesPage } from '../../utils/Events'; -import {SIZE} from '../../utils/SizeUtils'; -import {sleep} from '../../utils/TimeUtils'; -import {ActionIcon} from '../ActionIcon'; -import {TEMPLATE_DELETE} from '../DialogManager/Templates'; +import { SIZE } from '../../utils/SizeUtils'; +import { sleep } from '../../utils/TimeUtils'; +import { ActionIcon } from '../ActionIcon'; +import { TEMPLATE_DELETE } from '../DialogManager/Templates'; import Heading from '../Typography/Heading'; export const SelectionHeader = () => { diff --git a/apps/mobile/src/components/SimpleList/index.js b/apps/mobile/src/components/SimpleList/index.js index 6c3c5cd4d..761302a65 100644 --- a/apps/mobile/src/components/SimpleList/index.js +++ b/apps/mobile/src/components/SimpleList/index.js @@ -156,8 +156,7 @@ const SimpleList = ({ if (refreshCallback) { refreshCallback(); } - let user = await db.user.get(); - dispatch({type: Actions.USER, user: user}); + dispatch({type: Actions.LAST_SYNC,lastSync: await db.lastSynced()}); dispatch({type: Actions.ALL}); } }, []); diff --git a/apps/mobile/src/provider/Actions.js b/apps/mobile/src/provider/Actions.js index 559a3f013..0ea5e5ca9 100644 --- a/apps/mobile/src/provider/Actions.js +++ b/apps/mobile/src/provider/Actions.js @@ -31,5 +31,6 @@ export const Actions = { LOADING:"loading", FULLSCREEN:"fullscreen", DEVICE_MODE:"deviceMode", - MENU_PINS:"menuPins" + MENU_PINS:"menuPins", + LAST_SYNC:"lastSynced" }; diff --git a/apps/mobile/src/provider/DefaultState.js b/apps/mobile/src/provider/DefaultState.js index 0ac818c09..7367078c4 100644 --- a/apps/mobile/src/provider/DefaultState.js +++ b/apps/mobile/src/provider/DefaultState.js @@ -81,5 +81,6 @@ export const defaultState = { icon: 'account-outline', }, keyword: [], - menuPins:[] + menuPins:[], + lastSynced:"Never" }; diff --git a/apps/mobile/src/provider/Reducer.js b/apps/mobile/src/provider/Reducer.js index caa214dc5..8ab9b8f02 100644 --- a/apps/mobile/src/provider/Reducer.js +++ b/apps/mobile/src/provider/Reducer.js @@ -259,6 +259,13 @@ export const reducer = (state, action) => { menuPins: db.settings.pins, }; } + case Actions.LAST_SYNC: { + + return { + ...state, + menuPins: action.lastSync, + }; + } default: throw new Error('unknown action type'); } diff --git a/apps/mobile/src/services/Message.js b/apps/mobile/src/services/Message.js index c3d2a641f..053f5a019 100644 --- a/apps/mobile/src/services/Message.js +++ b/apps/mobile/src/services/Message.js @@ -1,27 +1,50 @@ -import { Actions } from "../provider/Actions"; -import { eOpenLoginDialog } from "../utils/Events"; -import { eSendEvent } from "./EventManager"; +import {Actions} from '../provider/Actions'; +import {eOpenLoginDialog} from '../utils/Events'; +import {eSendEvent} from './EventManager'; export function setLoginMessage(dispatch) { - dispatch({type:Actions.MESSAGE_BOARD_STATE,state:{ - visible:true, - message:'You are not logged in', - actionText:"Login to sync your notes", - onPress: () => { - eSendEvent(eOpenLoginDialog); - }, - data:{}, - icon:'account-outline' - }}); + dispatch({ + type: Actions.MESSAGE_BOARD_STATE, + state: { + visible: true, + message: 'You are not logged in', + actionText: 'Login to sync your notes', + onPress: () => { + eSendEvent(eOpenLoginDialog); + }, + data: {}, + icon: 'account-outline', + }, + }); +} + +export function setEmailVerifyMessage(dispatch) { + dispatch({ + type: Actions.MESSAGE_BOARD_STATE, + state: { + visible: true, + message: 'Email not verified', + actionText: 'Please verify your email to sync notes', + onPress: () => { + // Handle this + //eSendEvent(eOpen) + }, + data: {}, + icon: 'account-outline', + }, + }); } export function clearMessage(dispatch) { - dispatch({type:Actions.MESSAGE_BOARD_STATE,state:{ - visible:false, - message:'', - actionText:"", - onPress: null, - data:{}, - icon:'account-outline' - }}); -} \ No newline at end of file + dispatch({ + type: Actions.MESSAGE_BOARD_STATE, + state: { + visible: false, + message: '', + actionText: '', + onPress: null, + data: {}, + icon: 'account-outline', + }, + }); +} diff --git a/apps/mobile/src/services/PremiumService.js b/apps/mobile/src/services/PremiumService.js index 0dda70c68..6a7f4177f 100644 --- a/apps/mobile/src/services/PremiumService.js +++ b/apps/mobile/src/services/PremiumService.js @@ -7,7 +7,7 @@ let premiumStatus = true; async function setPremiumStatus() { try { - let user = await db.user.get(); + let user = await db.user.getUser(); if (!user || !user.id) { premiumStatus = null; } else { @@ -30,7 +30,7 @@ async function verify(callback,error) { return; */ try { - let user = await db.user.get(); + let user = await db.user.getUser(); if (!user || !user.id || premiumStatus) { if (error) { diff --git a/apps/mobile/src/services/Validation.js b/apps/mobile/src/services/Validation.js index 2f7cf020a..f4ba71422 100644 --- a/apps/mobile/src/services/Validation.js +++ b/apps/mobile/src/services/Validation.js @@ -31,6 +31,6 @@ export function validateUsername(username) { } export async function checkPremiumUser() { - let user = await db.user.get(); + //let user = await db.user.get(); return false; }