This commit is contained in:
ammarahm-ed
2020-09-27 10:15:19 +05:00
parent c6d41746da
commit eca49fce33
37 changed files with 656 additions and 667 deletions

View File

@@ -120,13 +120,13 @@ const App = () => {
try {
await db.init();
let user = await db.user.get();
console.log(user,"USER");
if (user) {
dispatch({type: ACTIONS.USER, user: user});
startSyncer();
}
} catch (e) {
error = e;
console.log(e.message);
} finally {
dispatch({type: ACTIONS.ALL});
setInit(true);
@@ -155,10 +155,8 @@ const App = () => {
if (!settings || !settings.includes('fontScale')) {
settings = defaultState.settings;
settings.fontScale = 1;
console.log(settings, 'SETTINGS');
await MMKV.setStringAsync('settings', JSON.stringify(settings));
}
console.log(e,"Initialize");
} finally {
let newColors = await getColorScheme(settings.useSystemTheme);
dispatch({type: ACTIONS.SETTINGS, settings: {...settings}});

View File

@@ -1864,7 +1864,7 @@
}
document.getElementById(dropdown).style.top = dropDownTop;
document.getElementById(dropdown).style.left = left;
console.log(dropDownTop, left);
//dropdown.css('top', dropDownTop + 'px');
//dropdown.css('left', left + 'px');
@@ -1876,7 +1876,6 @@
let downTop =
currentTop - b.offsetHeight - height;
console.log(downTop, 'nat')
document.getElementById(dropdown).style.top = downTop + 20;
document.getElementById(dropdown).style.left = left;

View File

@@ -1,6 +1,6 @@
import React, {useEffect, useState} from 'react';
import {Keyboard, Text, View} from 'react-native';
import {useSafeArea} from 'react-native-safe-area-context';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {pv, SIZE, WEIGHT} from '../../common/common';
import {useTracked} from '../../provider';
@@ -9,12 +9,10 @@ import {PressableButton} from '../PressableButton';
export const ContainerBottomButton = ({root}) => {
const [state, dispatch] = useTracked();
const {colors} = state;
const {colors,containerBottomButton} = state;
const [buttonHide, setButtonHide] = useState(false);
const insets = useSafeArea();
let containerBottomButton = root
? state.containerBottomButton
: state.indContainerBottomButton;
const insets = useSafeAreaInsets();
useEffect(() => {
Keyboard.addListener('keyboardDidShow', () => {
setTimeout(() => {

View File

@@ -1,12 +1,12 @@
import React from 'react';
import {KeyboardAvoidingView, Platform, SafeAreaView} from 'react-native';
import {useSafeArea} from 'react-native-safe-area-context';
import { useSafeAreaInsets} from 'react-native-safe-area-context';
import SelectionHeader from '../SelectionHeader';
import {ContainerBottomButton} from './ContainerBottomButton';
import {ContainerTopSection} from './ContainerTopSection';
export const Container = ({children,root}) => {
const insets = useSafeArea();
const insets = useSafeAreaInsets();
return (
<KeyboardAvoidingView

View File

@@ -22,7 +22,7 @@ import {
eOpenSimpleDialog,
eOpenPremiumDialog,
eClosePremiumDialog,
eOpenExportDialog
eOpenExportDialog,
} from '../../services/events';
import {DDS, hexToRGBA} from '../../utils/utils';
import ActionSheet from '../ActionSheet';
@@ -39,6 +39,8 @@ import LoginDialog from '../LoginDialog';
import PremiumDialog from '../Premium/PremiumDialog';
import ExportDialog from '../ExportDialog';
import RecoveryKeyDialog from '../RecoveryKeyDialog';
import PendingDialog from '../Premium/PendingDialog';
import PremiumStatusDialog from '../Premium/PremiumStatusDialog';
export class DialogManager extends Component {
constructor(props) {
@@ -71,7 +73,7 @@ export class DialogManager extends Component {
);
}
_showActionSheet = data => {
_showActionSheet = (data) => {
this.setState(
{
actionSheetData: data,
@@ -88,7 +90,6 @@ export class DialogManager extends Component {
};
_showMoveNote = () => {
///this.moveNoteDialog.open();
};
@@ -97,7 +98,7 @@ export class DialogManager extends Component {
// this.moveNoteDialog.close();
};
loadNote = i => {
loadNote = (i) => {
if (i && i.type === 'new') {
this.setState({
item: {},
@@ -110,7 +111,7 @@ export class DialogManager extends Component {
}
};
showAddTopic = notebook => {
showAddTopic = (notebook) => {
if (notebook) {
this.setState({
item: notebook,
@@ -182,7 +183,6 @@ export class DialogManager extends Component {
this.premiumDialog.close();
};
showLoginDialog = () => {
//this.loginDialog.open();
};
@@ -191,7 +191,7 @@ export class DialogManager extends Component {
//this.loginDialog.close();
};
showAddNotebook = data => {
showAddNotebook = (data) => {
this.setState(
{
item: data.item ? data.item : {},
@@ -205,7 +205,7 @@ export class DialogManager extends Component {
this.addNotebooksDialog.close();
};
_showSimpleDialog = data => {
_showSimpleDialog = (data) => {
this.setState(
{
simpleDialog: data,
@@ -215,7 +215,7 @@ export class DialogManager extends Component {
},
);
};
_hideSimpleDialog = data => {
_hideSimpleDialog = (data) => {
this.simpleDialog.hide();
};
@@ -258,12 +258,12 @@ export class DialogManager extends Component {
// this._showMoveNote();
break;
}
case "premium": {
case 'premium': {
eSendEvent(eOpenPremiumDialog);
break;
}
case "export": {
eSendEvent(eOpenExportDialog,[this.state.item]);
case 'export': {
eSendEvent(eOpenExportDialog, [this.state.item]);
break;
}
}
@@ -271,14 +271,13 @@ export class DialogManager extends Component {
this.show = null;
};
render() {
let {colors} = this.props;
let {actionSheetData, item, simpleDialog} = this.state;
return (
<>
<ActionSheet
ref={ref => (this.actionSheet = ref)}
ref={(ref) => (this.actionSheet = ref)}
containerStyle={{
backgroundColor: colors.bg,
width: DDS.isTab ? 500 : '100%',
@@ -313,7 +312,7 @@ export class DialogManager extends Component {
}}>
<ActionSheetComponent
item={item}
setWillRefresh={value => {
setWillRefresh={(value) => {
this.willRefresh = true;
}}
hasColors={actionSheetData.colors}
@@ -323,7 +322,7 @@ export class DialogManager extends Component {
}
rowItems={actionSheetData.rowItems}
columnItems={actionSheetData.columnItems}
close={value => {
close={(value) => {
if (value) {
this.show = value;
}
@@ -333,7 +332,7 @@ export class DialogManager extends Component {
</ActionSheet>
<Dialog
ref={ref => (this.simpleDialog = ref)}
ref={(ref) => (this.simpleDialog = ref)}
item={item}
colors={colors}
template={simpleDialog}
@@ -341,13 +340,10 @@ export class DialogManager extends Component {
<VaultDialog colors={colors} />
<MoveNoteDialog
colors={colors}
/>
<MoveNoteDialog colors={colors} />
<AddTopicDialog
ref={ref => (this.addTopicsDialog = ref)}
ref={(ref) => (this.addTopicsDialog = ref)}
toEdit={item.type === 'topic' ? item : null}
notebookID={
actionSheetData.extraData
@@ -357,19 +353,25 @@ export class DialogManager extends Component {
colors={colors}
/>
<AddNotebookDialog
ref={ref => (this.addNotebooksDialog = ref)}
ref={(ref) => (this.addNotebooksDialog = ref)}
toEdit={item}
colors={colors}
/>
<PremiumDialog ref={ref => this.premiumDialog = ref} colors={colors} />
<PremiumDialog
ref={(ref) => (this.premiumDialog = ref)}
colors={colors}
/>
<LoginDialog colors={colors} />
<MergeEditor />
<ExportDialog/>
<ExportDialog />
<RecoveryKeyDialog colors={colors} />
<PendingDialog colors={colors} />
<PremiumStatusDialog />
</>
);
}

View File

@@ -145,7 +145,6 @@ const ExportDialog = () => {
done={complete}
doneText={doneText}
onDone={() => {
console.log(result.type, result.filePath);
FileViewer.open(result.filePath, {
showOpenWithDialog: true,
showAppsSuggestions: true,

View File

@@ -1,13 +1,8 @@
import React from 'react';
import {
ActivityIndicator,
StyleSheet,
Text,
View
} from 'react-native';
import { ph, pv, SIZE, WEIGHT } from '../../common/common';
import { useTracked } from '../../provider';
import { Button } from '../Button';
import {ActivityIndicator, StyleSheet, Text, View} from 'react-native';
import {ph, pv, SIZE, WEIGHT} from '../../common/common';
import {useTracked} from '../../provider';
import {Button} from '../Button';
export const Loading = ({
height = 150,
@@ -32,13 +27,7 @@ export const Loading = ({
{doneText}
</Text>
<Button
onPress={onDone}
title="Open File"
/>
<Button onPress={onDone} title="Open File" />
</>
) : (
<>
@@ -56,7 +45,7 @@ const styles = StyleSheet.create({
activityText: {
fontSize: SIZE.sm,
textAlign: 'center',
marginBottom:10
marginBottom: 10,
},
activityContainer: {
alignItems: 'center',

View File

@@ -34,7 +34,6 @@ const LoginDialog = () => {
const [state, dispatch] = useTracked();
const colors = state.colors;
const [visible, setVisible] = useState(false);
const [animated, setAnimated] = useState(false);
const [status, setStatus] = useState('Logging you in');
const [loggingIn, setLoggingIn] = useState(false);
const [email, setEmail] = useState(null);
@@ -71,8 +70,22 @@ const LoginDialog = () => {
}
const close = () => {
_email.current?.clear();
_pass.current?.clear();
_passConfirm.current?.clear();
_username.current?.clear();
setVisible(false);
setAnimated(false);
setUsername(null);
setPassword(null);
setConfirmPassword(null);
setKey(null);
setLogin(true);
setModalVisible(false);
setUserConsent(false);
setEmail(false);
setLoggingIn(false);
};
const loginUser = async () => {
@@ -123,6 +136,7 @@ const LoginDialog = () => {
}
};
const validateInfo = () => {
if (!password || !email || !username || !passwordReEnter) {
ToastEvent.show('All fields are required', 'error', 'local');
@@ -312,10 +326,7 @@ const LoginDialog = () => {
</Text>
<TouchableOpacity
onPress={() => {
DDS.isTab
? eSendEvent(eCloseLoginDialog)
: navigation.navigate('Home');
setModalVisible(false);
close();
}}
activeOpacity={opacity}
style={{
@@ -348,7 +359,7 @@ const LoginDialog = () => {
name="arrow-left"
size={SIZE.xxxl}
onPress={() => {
setVisible(false);
close();
}}
style={{
width: 50,
@@ -459,6 +470,7 @@ const LoginDialog = () => {
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
color: colors.pri,
}}
placeholder="Username (a-z _- 0-9)"
placeholderTextColor={colors.icon}
@@ -548,6 +560,7 @@ const LoginDialog = () => {
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
color: colors.pri,
}}
placeholder="Email"
placeholderTextColor={colors.icon}
@@ -648,6 +661,7 @@ const LoginDialog = () => {
fontFamily: WEIGHT.regular,
width: '85%',
maxWidth: '85%',
color: colors.pri,
}}
secureTextEntry={secureEntry}
placeholder="Password (6+ characters)"
@@ -736,6 +750,7 @@ const LoginDialog = () => {
borderRadius: 5,
fontSize: SIZE.sm,
fontFamily: WEIGHT.regular,
color: colors.pri,
}}
secureTextEntry={secureEntry}
placeholder="Confirm Password"

View File

@@ -115,7 +115,7 @@ export const UserSection = ({noTextMode}) => {
}}>
{syncing ? 'Syncing ' : 'Synced '}
{!syncing ? (
user?.notesnook?.lastSynced !== 0 ? (
user?.notesnook?.lastSynced ? (
<TimeSince time={user.notesnook.lastSynced} />
) : (
'never'

View File

@@ -27,7 +27,6 @@ const MoveNoteDialog = () => {
const [state, dispatch] = useTracked();
const {notebooks, colors, selectedItemsList} = state;
const [visible, setVisible] = useState(false);
const [animated, setAnimated] = useState(false);
const [expanded, setExpanded] = useState('');
const [notebookInputFocused, setNotebookInputFocused] = useState(false);
const [topicInputFocused, setTopicInputFocused] = useState(false);
@@ -39,7 +38,6 @@ const MoveNoteDialog = () => {
const close = () => {
setVisible(false);
setAnimated(false);
setExpanded(false);
newTopicTitle = null;
newNotebookTitle = null;

View File

@@ -1,11 +1,10 @@
import React from 'react';
import {Dimensions, Text, TouchableOpacity, View} from 'react-native';
import { Dimensions, Text, View } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {ph, SIZE, WEIGHT} from '../../common/common';
import {timeSince} from '../../utils/utils';
import {ActionIcon} from '../ActionIcon';
import {ActionSheetEvent} from '../DialogManager/recievers';
import {PressableButton} from '../PressableButton';
import { ph, SIZE, WEIGHT } from '../../common/common';
import { timeSince } from '../../utils/utils';
import { ActionIcon } from '../ActionIcon';
import { ActionSheetEvent } from '../DialogManager/recievers';
const w = Dimensions.get('window').width;
const h = Dimensions.get('window').height;

View File

@@ -0,0 +1,103 @@
import React, {createRef} from 'react';
import {Text, View} from 'react-native';
import {SIZE, WEIGHT} from '../../common/common';
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/eventManager';
import {eClosePendingDialog, eOpenPendingDialog} from '../../services/events';
import {db, w} from '../../utils/utils';
import ActionSheet from '../ActionSheet';
import Seperator from '../Seperator';
const actionSheet = createRef();
class PendingDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null,
product: null,
};
}
async open() {
actionSheet.current?._setModalVisible(true);
let u = await db.user.get();
this.setState({
user: u && u.Id ? u : null,
});
}
close() {
actionSheet.current?._setModalVisible(false);
this.setState({
user: null,
});
}
async componentDidMount() {
eSubscribeEvent(eOpenPendingDialog, this.open.bind(this));
eSubscribeEvent(eClosePendingDialog, this.close.bind(this));
let u = await db.user.get();
this.setState({
user: u && u.Id ? u : null,
});
}
componentWillUnmount() {
eUnSubscribeEvent(eOpenPendingDialog, this.open);
eUnSubscribeEvent(eClosePendingDialog, this.close);
}
render() {
const {colors} = this.props;
return (
<ActionSheet
containerStyle={{
backgroundColor: colors.bg,
width: '100%',
alignSelf: 'center',
borderRadius: 10,
}}
gestureEnabled={true}
ref={actionSheet}
initialOffsetFromBottom={1}>
<View
style={{
width: w,
backgroundColor: colors.bg,
justifyContent: 'space-between',
paddingHorizontal: 12,
borderRadius: 10,
paddingTop: 10,
}}>
<Text
style={{
fontSize: SIZE.xxxl,
fontFamily: WEIGHT.bold,
color: colors.accent,
paddingBottom: 20,
paddingTop: 10,
alignSelf: 'center',
}}>
Thank you!
</Text>
<Seperator />
<Text
style={{
fontSize: SIZE.md,
fontFamily: WEIGHT.regular,
color: colors.pri,
width: '80%',
alignSelf: 'center',
textAlign: 'center',
}}>
We are processing your subscription. You account will be upgraded to
Notesnook Pro very soon.
</Text>
<Seperator />
</View>
</ActionSheet>
);
}
}
export default PendingDialog;

View File

@@ -4,8 +4,8 @@ import * as RNIap from 'react-native-iap';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {SIZE, WEIGHT} from '../../common/common';
import {eSendEvent} from '../../services/eventManager';
import {eOpenLoginDialog} from '../../services/events';
import {db, h, itemSkus, w} from '../../utils/utils';
import {eOpenLoginDialog, eOpenPendingDialog} from '../../services/events';
import {db, h, itemSkus, ToastEvent, w} from '../../utils/utils';
import ActionSheet from '../ActionSheet';
import {Button} from '../Button';
import Seperator from '../Seperator';
@@ -19,6 +19,12 @@ class PremiumDialog extends React.Component {
this.routeIndex = 0;
this.count = 0;
this.actionSheetRef = createRef();
this.subsriptionSuccessListerner = RNIap.purchaseUpdatedListener(
this.onSuccessfulSubscription,
);
this.subsriptionErrorListener = RNIap.purchaseErrorListener(
this.onSubscriptionError,
);
}
open() {
@@ -37,7 +43,22 @@ class PremiumDialog extends React.Component {
product: prod[0],
});
}
componentDidUpdate() {}
onSuccessfulSubscription = (subscription: RNIap.SubscriptionPurchase) => {
const receipt = subscription.transactionReceipt;
if (receipt) {
this.close();
setTimeout(() => {
eSendEvent(eOpenPendingDialog);
}, 500);
}
};
onSubscriptionError = (error: RNIap.PurchaseError) => {
console.log(error.message, 'Error');
ToastEvent.show(error.message);
};
render() {
const {colors} = this.props;
@@ -68,7 +89,7 @@ class PremiumDialog extends React.Component {
color: colors.heading,
paddingBottom: 20,
paddingTop: 10,
alignSelf:'center'
alignSelf: 'center',
}}>
Notesnook Pro
</Text>
@@ -180,7 +201,9 @@ class PremiumDialog extends React.Component {
color: colors.pri,
fontFamily: WEIGHT.regular,
}}>
Start your 14 Day Free Trial (no credit card needed)
{this.state.user
? 'Cancel anytime in Subscriptions on Google Play'
: 'Start your 14 Day Trial for Free (no credit card needed)'}
</Text>
</Text>
<Text
@@ -207,10 +230,16 @@ class PremiumDialog extends React.Component {
eSendEvent(eOpenLoginDialog);
}, 400);
} else {
// Request
RNIap.requestSubscription(this.state.product.productId)
.then((r) => {})
.catch((e) => {
console.log(e);
});
}
}}
title={this.state.user ? 'Buy Subscription' : 'Sign Up Now'}
title={
this.state.user ? 'Subscribe to Notesnook Pro' : 'Sign Up Now'
}
height={50}
width="100%"
/>

View File

@@ -0,0 +1,136 @@
import React, {useEffect, useState} from 'react';
import {Modal, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {ph, pv, SIZE, WEIGHT} from '../../common/common';
import {useTracked} from '../../provider';
import {DDS, getElevation} from '../../utils/utils';
import Seperator from '../Seperator';
const {
eSubscribeEvent,
eUnSubscribeEvent,
} = require('../../services/eventManager');
const {
eOpenPremiumStatusDialog,
eClosePremiumStatusDialog,
} = require('../../services/events');
const PremiumStatusDialog = () => {
const [state, dispatch] = useTracked();
const {colors, premiumUser} = state;
const [visible, setVisible] = useState(false);
useEffect(() => {
eSubscribeEvent(eOpenPremiumStatusDialog, open);
eSubscribeEvent(eClosePremiumStatusDialog, close);
return () => {
eUnSubscribeEvent(eOpenPremiumStatusDialog, open);
eUnSubscribeEvent(eClosePremiumStatusDialog, close);
};
}, []);
const open = (data) => {
setVisible(true);
};
const close = (data) => {
setVisible(false);
};
return (
<Modal
visible={visible}
transparent={true}
animated
animationType="fade"
onRequestClose={close}>
<View style={styles.wrapper}>
<TouchableOpacity onPress={close} style={styles.overlay} />
<View
style={[
{
width: DDS.isTab ? '40%' : '80%',
backgroundColor: colors.bg,
},
styles.container,
]}>
<View style={styles.headingContainer}>
<Text style={[{color: colors.accent}, styles.heading]}>
Notesnook Pro
</Text>
</View>
<Seperator />
<Text
style={{
color: colors.pri,
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
textAlign: 'center',
width: '90%',
alignSelf: 'center',
}}>
Your account has been upgraded to Notesnook Pro successfully. Now
you can enjoy all premium features!
</Text>
<Seperator />
</View>
</View>
</Modal>
);
};
const styles = StyleSheet.create({
wrapper: {
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.3)',
justifyContent: 'center',
alignItems: 'center',
},
container: {
...getElevation(5),
maxHeight: 350,
borderRadius: 5,
paddingHorizontal: ph,
paddingVertical: pv,
},
headingContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
buttonContainer: {
justifyContent: 'space-between',
alignItems: 'center',
},
heading: {
fontFamily: WEIGHT.bold,
marginLeft: 5,
fontSize: SIZE.xxxl,
},
button: {
paddingVertical: pv,
paddingHorizontal: ph,
marginTop: 10,
borderRadius: 5,
width: '100%',
justifyContent: 'center',
alignItems: 'center',
borderWidth: 1,
flexDirection: 'row',
},
buttonText: {
fontFamily: WEIGHT.medium,
color: 'white',
fontSize: SIZE.sm,
marginLeft: 5,
},
overlay: {
width: '100%',
height: '100%',
position: 'absolute',
},
});
export default PremiumStatusDialog;

View File

@@ -32,9 +32,10 @@ class RecoveryKeyDialog extends React.Component {
async componentDidMount() {
eSubscribeEvent(eOpenRecoveryKeyDialog, this.open);
let k = await db.user.key();
if (k) {
this.setState({
key: k,
key: k.key,
});
}
}
@@ -47,7 +48,6 @@ class RecoveryKeyDialog extends React.Component {
saveQRCODE = () => {
this.svg.current?.toDataURL((data) => {
console.log(data);
RNFetchBlob.fs
.writeFile(
RNFetchBlob.fs.dirs.SDCardDir +

View File

@@ -18,11 +18,10 @@ let timeoutAnimate = null;
let animating = false;
export const Search = (props) => {
const [state, dispatch] = useTracked();
const {colors, searchResults} = state;
const {colors, searchResults,searchState} = state;
const [text, setText] = useState('');
const [focus, setFocus] = useState(false);
let searchState = props.root ? state.searchState : state.indSearchState;
const _marginAnim = new Value(0);
const _opacity = new Value(1);

View File

@@ -19,7 +19,6 @@ export const SelectionHeader = () => {
selectionMode,
selectedItemsList,
currentScreen,
containerState,
premiumUser,
} = state;
const [selectAll, setSelectAll] = useState(false);
@@ -34,7 +33,7 @@ export const SelectionHeader = () => {
}).start();
}, [selectionMode]);
return containerState.noSelectionHeader ? null : (
return (
<Animated.View
style={{
width: '100%',

View File

@@ -12,11 +12,8 @@ export const NotebookItemWrapper = ({
pinned = false,
}) => {
const [state, dispatch] = useTracked();
const {selectionMode, preventDefaultMargins} = state;
let headerState = preventDefaultMargins
? state.indHeaderState
: state.headerState;
let params = headerState.route.params ? headerState.route.params : {};
const {selectionMode, preventDefaultMargins, headerState} = state;
let params = headerState.route.params || {};
const style = useMemo(() => {
return {width: selectionMode ? '90%' : '100%', marginHorizontal: 0};
@@ -77,8 +74,6 @@ export const NotebookItemWrapper = ({
item={item}>
<NotebookItem
hideMore={preventDefaultMargins}
navigation={headerState.navigation}
route={headerState.route}
isTopic={item.type === 'topic'}
customStyle={style}
noteToMove={params.note}

View File

@@ -1,4 +1,5 @@
import React, {useEffect, useState} from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import {StyleSheet} from 'react-native';
import {Dimensions, Platform, RefreshControl, Text, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
@@ -28,6 +29,7 @@ const SimpleList = ({
focused,
customRefresh,
customRefreshing,
refreshCallback,
}) => {
const [state, dispatch] = useTracked();
const {colors, selectionMode, user} = state;
@@ -56,7 +58,6 @@ const SimpleList = ({
/* for (var i = 0; i < 10000; i++) {
d = [...d,...data];
} */
console.log(d, 'D');
setDataProvider(
new DataProvider((r1, r2) => {
return r1 !== r2;
@@ -84,17 +85,12 @@ const SimpleList = ({
const RenderSectionHeader = ({item}) => (
<Text
style={{
fontFamily: WEIGHT.bold,
fontSize: SIZE.xs + 1,
style={[
{
color: colors.accent,
paddingHorizontal: 12,
width: '100%',
alignSelf: 'center',
marginTop: 15,
height: 18,
paddingBottom: 5,
}}>
},
styles.sectionHeader,
]}>
{item.title}
</Text>
);
@@ -133,21 +129,21 @@ const SimpleList = ({
} else {
setRefreshing(false);
}
if (refreshCallback) {
refreshCallback();
}
dispatch({type: ACTIONS.ALL});
}
};
const _ListEmptyComponent = (
<View
style={{
height: '100%',
width: '100%',
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'center',
opacity: 1,
style={[
{
backgroundColor: colors.bg,
}}>
},
styles.emptyList,
]}>
<>{placeholder}</>
</View>
);
@@ -204,6 +200,22 @@ const SimpleList = ({
}
};
const listStyle = useMemo(() => {
return {
height: '100%',
backgroundColor: colors.bg,
width: '100%',
paddingTop:
Platform.OS == 'ios'
? listData[0] && !selectionMode
? 115
: 115 - 60
: listData[0] && !selectionMode
? 155 - insets.top
: 155 - insets.top - 60,
};
}, []);
return !listData || listData.length === 0 ? (
_ListEmptyComponent
) : (
@@ -228,19 +240,7 @@ const SimpleList = ({
minHeight: '100%',
},
}}
style={{
height: '100%',
backgroundColor: colors.bg,
width: '100%',
paddingTop:
Platform.OS == 'ios'
? listData[0] && !selectionMode
? 115
: 115 - 60
: listData[0] && !selectionMode
? 155 - insets.top
: 155 - insets.top - 60,
}}
style={listStyle}
/>
);
};
@@ -253,14 +253,7 @@ const SearchHeader = () => {
const searchResults = {...state.searchResults};
return (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingHorizontal: 12,
height: 40,
}}>
<View style={styles.searchHeader}>
<Text
style={{
fontFamily: WEIGHT.bold,
@@ -307,17 +300,7 @@ const LoginCard = ({type, data}) => {
}
alpha={!colors.night ? -0.02 : 0.1}
opacity={0.12}
customStyle={{
width: '100%',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
paddingHorizontal: 12,
alignSelf: 'center',
height: 40,
borderRadius: 0,
position: 'relative',
}}>
customStyle={styles.loginCard}>
<View
style={{
width: 25,
@@ -330,10 +313,7 @@ const LoginCard = ({type, data}) => {
justifyContent: 'center',
}}>
<Icon
style={{
textAlign: 'center',
textAlignVertical: 'center',
}}
style={styles.loginIcon}
name="account-outline"
color="white"
size={SIZE.xs}
@@ -377,3 +357,46 @@ const ListHeaderComponent = ({type, data}) => {
<LoginCard type={type} data={data} />
);
};
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: 15,
height: 18,
paddingBottom: 5,
},
emptyList: {
height: '100%',
width: '100%',
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'center',
opacity: 1,
},
});

View File

@@ -1,11 +1,9 @@
import React, {createRef} from 'react';
import {TouchableOpacity} from 'react-native';
import Menu, {MenuDivider, MenuItem} from 'react-native-material-menu';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {SIZE, WEIGHT} from '../../common/common';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {ActionIcon} from '../ActionIcon';
import React, { createRef } from 'react';
import Menu, { MenuDivider, MenuItem } from 'react-native-material-menu';
import { SIZE, WEIGHT } from '../../common/common';
import { useTracked } from '../../provider';
import { ACTIONS } from '../../provider/actions';
import { ActionIcon } from '../ActionIcon';
const menuRef = createRef();
export const HeaderMenu = () => {
const [state, dispatch] = useTracked();
@@ -13,6 +11,7 @@ export const HeaderMenu = () => {
return headerVerticalMenu ? (
<Menu
ref={menuRef}
animationDuration={200}
style={{

View File

@@ -1,22 +1,22 @@
import React from 'react';
import { Text } from 'react-native';
import { SIZE, WEIGHT } from '../../common/common';
import { useTracked } from '../../provider';
import {Text} from 'react-native';
import {SIZE, WEIGHT} from '../../common/common';
import {useTracked} from '../../provider';
export const HeaderTitle = ({root}) => {
const [state, dispatch] = useTracked();
const {colors} = state;
let headerTextState = root ? state.headerTextState : state.indHeaderTextState;
const {colors, headerTextState} = state;
const style = {
fontSize: SIZE.xl,
color: headerTextState.color || colors.heading,
fontFamily: WEIGHT.bold,
alignSelf: 'center',
};
return (
<>
<Text
style={{
fontSize: SIZE.xl,
color: headerTextState.color ? headerTextState.color : colors.heading,
fontFamily: WEIGHT.bold,
alignSelf: 'center',
}}>
<Text style={style}>
<Text
style={{
color: colors.accent,

View File

@@ -1,20 +1,12 @@
import React from 'react';
import {
ActivityIndicator,
Platform,
StyleSheet,
TouchableOpacity,
View,
} from 'react-native';
import {ActivityIndicator, Platform, StyleSheet, View} from 'react-native';
import * as Animatable from 'react-native-animatable';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {SIZE} from '../../common/common';
import {useTracked} from '../../provider';
import {eSendEvent} from '../../services/eventManager';
import NavigationService from '../../services/NavigationService';
import {useHideHeader} from '../../utils/hooks';
import {sideMenuRef} from '../../utils/refs';
import {DDS, w} from '../../utils/utils';
import {ActionIcon} from '../ActionIcon';
import {HeaderMenu} from './HeaderMenu';
@@ -22,9 +14,7 @@ import {HeaderTitle} from './HeaderTitle';
export const Header = ({showSearch, root}) => {
const [state, dispatch] = useTracked();
const {colors, syncing} = state;
let headerState = root ? state.headerState : state.indHeaderState;
const {colors, syncing, headerState} = state;
const insets = useSafeAreaInsets();
const hideHeader = useHideHeader();

View File

@@ -60,18 +60,13 @@ export const defaultState = {
canGoBack: true,
menu: false,
verticalMenu: false,
navigation: null,
headerColor: null,
route: {},
},
headerTextState: {
heading: 'Notes',
color: null,
},
headerVerticalMenu: true,
containerState: {
noSelectionHeader: false,
},
searchState: {
noSearch: false,
data: [],
@@ -84,30 +79,5 @@ export const defaultState = {
bottomButtonOnPress: () => {},
bottomButtonText: 'Create a new note',
},
indHeaderState: {
heading: 'Home',
canGoBack: true,
menu: false,
verticalMenu: false,
navigation: null,
headerColor: null,
route: {},
},
indHeaderTextState: {
heading: 'Notes',
color: null,
},
indSearchState: {
noSearch: false,
data: [],
type: 'notes',
color: null,
placeholder: 'Search all notes',
},
indContainerBottomButton: {
visible: true,
bottomButtonOnPress: () => {},
bottomButtonText: 'Create a new note',
},
keyword: [],
};

View File

@@ -197,42 +197,22 @@ export const reducer = (state, action) => {
};
}
case ACTIONS.HEADER_STATE: {
let header = action.state.ind
? {
...state.indHeaderState,
...action.state,
}
: {
let header = {
...state.headerState,
...action.state,
};
return action.state.ind
? {
...state,
indHeaderState: {...header},
}
: {
return {
...state,
headerState: header,
};
}
case ACTIONS.SEARCH_STATE: {
let stat = action.state.ind
? {
...state.indSearchState,
...action.state,
}
: {
let stat = {
...state.searchState,
...action.state,
};
return action.state.ind
? {
...state,
indSearchState: stat,
}
: {
return {
...state,
searchState: stat,
};
@@ -244,21 +224,11 @@ export const reducer = (state, action) => {
};
}
case ACTIONS.HEADER_TEXT_STATE: {
let stat = action.state.ind
? {
...state.indHeaderTextState,
...action.state,
}
: {
let stat ={
...state.headerTextState,
...action.state,
};
return action.state.ind
? {
...state,
indHeaderTextState: stat,
}
: {
return {
...state,
headerTextState: stat,
};
@@ -270,21 +240,11 @@ export const reducer = (state, action) => {
};
}
case ACTIONS.CONTAINER_BOTTOM_BUTTON: {
let containerBottomButton = action.state.ind
? {
...state.indContainerBottomButton,
...action.state,
}
: {
let containerBottomButton = {
...state.containerBottomButton,
...action.state,
};
return action.state.ind
? {
...state,
indContainerBottomButton: containerBottomButton,
}
: {
return {
...state,
containerBottomButton: containerBottomButton,
};

View File

@@ -91,3 +91,11 @@ export const eCloseExportDialog = '544';
export const eOpenRecoveryKeyDialog = '545';
export const eCloseRecoveryKeyDialog = '546';
export const eOpenPendingDialog = '547';
export const eClosePendingDialog = '548';
export const eOpenPremiumStatusDialog = '549';
export const eClosePremiumStatusDialog = '550';

View File

@@ -1,12 +1,12 @@
import he from 'he';
import { Platform } from 'react-native';
import {Platform} from 'react-native';
import 'react-native-get-random-values';
import RNHTMLtoPDF from 'react-native-html-to-pdf';
import MMKVStorage from 'react-native-mmkv-storage';
import { generateSecureRandom } from 'react-native-securerandom';
import {generateSecureRandom} from 'react-native-securerandom';
import Sodium from 'react-native-sodium';
import RNFetchBlob from 'rn-fetch-blob';
import { db, requestStoragePermission, ToastEvent } from './utils';
import {db, requestStoragePermission, ToastEvent} from './utils';
export const MMKV = new MMKVStorage.Loader().initialize();
async function read(key, isArray = false) {
let data;
@@ -116,7 +116,7 @@ async function saveToMarkdown(note) {
RNFetchBlob.fs.dirs.SDCardDir + '/Notesnook/exported/Markdown/';
await checkAndCreateDir(androidSavePath);
let markdown = await db.notes.note(note.id).export('md');
console.log(markdown);
let path = androidSavePath + note.title + '.md';
await RNFetchBlob.fs.writeFile(path, markdown, 'utf8');
@@ -132,7 +132,6 @@ async function saveToText(note) {
RNFetchBlob.fs.dirs.SDCardDir + '/Notesnook/exported/Text/';
await checkAndCreateDir(androidSavePath);
let markdown = await db.notes.note(note.id).export('txt');
console.log(markdown);
let path = androidSavePath + note.title + '.txt';
await RNFetchBlob.fs.writeFile(path, markdown, 'utf8');
@@ -149,7 +148,7 @@ async function saveToHTML(note) {
RNFetchBlob.fs.dirs.SDCardDir + '/Notesnook/exported/Html/';
await checkAndCreateDir(androidSavePath);
let markdown = await db.notes.note(note.id).export('html');
console.log(markdown);
let path = androidSavePath + note.title + '.html';
await RNFetchBlob.fs.writeFile(path, markdown, 'utf8');

View File

@@ -66,7 +66,6 @@ export async function requestStoragePermission() {
RESULTS.GRANTED &&
response['android.permission.WRITE_EXTERNAL_STORAGE'] === RESULTS.GRANTED;
} catch (err) {
console.log(error);
} finally {
return granted;
}

View File

@@ -1,32 +1,16 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import SimpleList from '../../components/SimpleList';
import {NoteItemWrapper} from '../../components/SimpleList/NoteItemWrapper';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {db, ToastEvent} from '../../utils/utils';
import { useIsFocused } from '@react-navigation/native';
import React, { useEffect, useState } from 'react';
import { Placeholder } from '../../components/ListPlaceholders';
import SimpleList from '../../components/SimpleList';
import { NoteItemWrapper } from '../../components/SimpleList/NoteItemWrapper';
import { useTracked } from '../../provider';
import { ACTIONS } from '../../provider/actions';
export const Favorites = ({route, navigation}) => {
const [state, dispatch] = useTracked();
const {favorites} = state;
const [refreshing, setRefreshing] = useState(false);
const isFocused = useIsFocused();
const _onRefresh = async () => {
setRefreshing(true);
try {
await db.sync();
dispatch({type: ACTIONS.FAVORITES});
dispatch({type: ACTIONS.USER});
setRefreshing(false);
ToastEvent.show('Sync Complete', 'success');
} catch (e) {
setRefreshing(false);
ToastEvent.show('Sync failed, network error', 'error');
}
};
useEffect(() => {
if (isFocused) {
dispatch({
@@ -35,9 +19,7 @@ export const Favorites = ({route, navigation}) => {
type: 'notes',
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({
@@ -46,10 +28,6 @@ export const Favorites = ({route, navigation}) => {
visible: false,
},
});
dispatch({
type: ACTIONS.HEADER_VERTICAL_MENU,
state: false,
});
dispatch({
type: ACTIONS.HEADER_TEXT_STATE,
@@ -85,9 +63,11 @@ export const Favorites = ({route, navigation}) => {
<SimpleList
data={favorites}
type="notes"
refreshCallback={() => {
dispatch({type: ACTIONS.FAVORITES});
}}
refreshing={refreshing}
focused={isFocused}
onRefresh={_onRefresh}
RenderItem={NoteItemWrapper}
placeholder={<Placeholder type="favorites" />}
placeholderText="Notes you favorite appear here"

View File

@@ -1,15 +1,11 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect} from 'react';
import {BackHandler} from 'react-native';
import {AddNotebookEvent} from '../../components/DialogManager/recievers';
import {Placeholder} from '../../components/ListPlaceholders';
import SimpleList from '../../components/SimpleList';
import {NotebookItemWrapper} from '../../components/SimpleList/NotebookItemWrapper';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {eSendEvent} from '../../services/eventManager';
import {eScrollEvent} from '../../services/events';
import NavigationService from '../../services/NavigationService';
import {Placeholder} from '../../components/ListPlaceholders';
export const Folders = ({route, navigation}) => {
const [state, dispatch] = useTracked();
const {notebooks} = state;
@@ -23,9 +19,7 @@ export const Folders = ({route, navigation}) => {
type: 'notebooks',
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({

View File

@@ -26,22 +26,13 @@ export const Home = ({route, navigation}) => {
type: 'notes',
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({
type: ACTIONS.HEADER_VERTICAL_MENU,
state: true,
});
dispatch({
type: ACTIONS.CONTAINER_BOTTOM_BUTTON,
state: {
bottomButtonText: 'Create a new Note',
},
});
dispatch({
type: ACTIONS.HEADER_TEXT_STATE,
state: {
@@ -68,8 +59,18 @@ export const Home = ({route, navigation}) => {
eSendEvent(eScrollEvent, 0);
dispatch({type: ACTIONS.COLORS});
dispatch({type: ACTIONS.NOTES});
dispatch({type: ACTIONS.PINNED});
} else {
dispatch({
type: ACTIONS.HEADER_VERTICAL_MENU,
state: false,
});
}
return () => {
dispatch({
type: ACTIONS.HEADER_VERTICAL_MENU,
state: false,
});
};
}, [isFocused]);
useEffect(() => {

View File

@@ -1,4 +1,4 @@
import {useIsFocused} from '@react-navigation/native';
/* import {useIsFocused} from '@react-navigation/native';
import React, {createRef, useEffect, useState} from 'react';
import {
ActivityIndicator,
@@ -92,7 +92,7 @@ export const Login = ({route, navigation}) => {
try {
let res = await db.user.login(username.toLowerCase(), password);
console.log(res, username, password);
if (res) {
setStatus('Fetching data...');
}
@@ -471,3 +471,4 @@ export const Login = ({route, navigation}) => {
};
export default Login;
*/

View File

@@ -16,7 +16,7 @@ import NavigationService from '../../services/NavigationService';
import {db, ToastEvent} from '../../utils/utils';
export const Notebook = ({route, navigation}) => {
const [state, dispatch] = useTracked();
const [, dispatch] = useTracked();
const [topics, setTopics] = useState([]);
const [refreshing, setRefreshing] = useState(false);
@@ -52,9 +52,7 @@ export const Notebook = ({route, navigation}) => {
menu: false,
canGoBack: true,
heading: params.title,
route: route,
color: null,
navigation: navigation,
},
});
@@ -104,27 +102,16 @@ export const Notebook = ({route, navigation}) => {
}
}, [topics, isFocused]);
const _onRefresh = async () => {
setRefreshing(true);
try {
await db.sync();
onLoad();
dispatch({type: ACTIONS.USER});
setRefreshing(false);
ToastEvent.show('Sync Complete', 'success');
} catch (e) {
setRefreshing(false);
ToastEvent.show('Sync failed, network error', 'error');
}
};
return (
<SimpleList
data={topics}
type="topics"
customRefreshing={refreshing}
refreshCallback={() => {
onLoad();
}}
focused={isFocused}
customRefresh={_onRefresh}
RenderItem={RenderItem}
placeholder={<></>}
placeholderText=""

View File

@@ -1,7 +1,9 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import {COLORS_NOTE} from '../../common/common';
import {Placeholder} from '../../components/ListPlaceholders';
import SimpleList from '../../components/SimpleList';
import {NotebookItemWrapper} from '../../components/SimpleList/NotebookItemWrapper';
import {NoteItemWrapper} from '../../components/SimpleList/NoteItemWrapper';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {
@@ -16,9 +18,6 @@ import {
} from '../../services/events';
import {openEditorAnimation} from '../../utils/animations';
import {db, DDS, editing, ToastEvent} from '../../utils/utils';
import {NoteItemWrapper} from '../../components/SimpleList/NoteItemWrapper';
import {Placeholder} from '../../components/ListPlaceholders';
import {COLORS_NOTE} from '../../common/common';
export const Notes = ({route, navigation}) => {
const [state, dispatch] = useTracked();
@@ -30,20 +29,13 @@ export const Notes = ({route, navigation}) => {
let params = route.params ? route.params : null;
useEffect(() => {
if (isFocused) {
if (!params) {
params = {
title: 'Notes',
};
}
}, []);
useEffect(() => {
if (isFocused) {
init();
dispatch({
type: ACTIONS.CURRENT_SCREEN,
screen: params.type === "color"? params.color.title : params.type,
});
} else {
setNotes([]);
editing.actionAfterFirstSave = {
@@ -67,21 +59,20 @@ export const Notes = ({route, navigation}) => {
if (data) {
params = data;
}
let allNotes = [];
eSendEvent(eScrollEvent, 0);
if (params.type === 'tag') {
let notesInTag = db.notes.tagged(params.tag.title);
setNotes([...notesInTag]);
allNotes = db.notes.tagged(params.tag.title);
} else if (params.type == 'color') {
let notesInColors = db.notes.colored(params.color.title);
setNotes([...notesInColors]);
allNotes = db.notes.colored(params.color.title);
} else {
let allNotes = db.notebooks
allNotes = db.notebooks
.notebook(params.notebookId)
.topics.topic(params.title).all;
}
if (allNotes && allNotes.length > 0) {
setNotes([...allNotes]);
}
}
};
useEffect(() => {
@@ -92,9 +83,8 @@ export const Notes = ({route, navigation}) => {
type: 'notes',
menu: params.type === 'color' ? true : false,
canGoBack: params.type === 'color' ? false : true,
route: route,
color: params.type == 'color' ? COLORS_NOTE[params.title] : null,
navigation: navigation,
},
});
dispatch({
@@ -122,7 +112,7 @@ export const Notes = ({route, navigation}) => {
init();
dispatch({
type: ACTIONS.CURRENT_SCREEN,
screen: params.type === "color"? params.color.title : params.type,
screen: params.type === 'color' ? params.color.title : params.type,
});
} else {
setNotes([]);
@@ -149,20 +139,6 @@ export const Notes = ({route, navigation}) => {
}
}, [notes, isFocused]);
const _onRefresh = async () => {
setRefreshing(true);
try {
await db.sync();
init();
dispatch({type: ACTIONS.USER});
setRefreshing(false);
ToastEvent.show('Sync Complete', 'success');
} catch (e) {
setRefreshing(false);
ToastEvent.show('Sync failed, network error', 'error');
}
};
const _bottomBottomOnPress = () => {
if (params.type === 'tag') {
editing.actionAfterFirstSave = {
@@ -184,19 +160,18 @@ export const Notes = ({route, navigation}) => {
if (DDS.isTab) {
eSendEvent(eOnLoadNote, {type: 'new'});
} else {
eSendEvent(eOnLoadNote, {type: 'new'});
openEditorAnimation();
}
openEditorAnimation();
};
return (
<SimpleList
data={notes}
type="notes"
customRefreshing={refreshing}
refreshCallback={() => {
init();
}}
focused={isFocused}
customRefresh={_onRefresh}
RenderItem={NoteItemWrapper}
placeholder={<Placeholder type="notes" />}
placeholderText={`Add some notes to this" ${

View File

@@ -1,10 +1,8 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect, useState} from 'react';
import React, {useEffect} from 'react';
import {
Appearance,
Clipboard,
Linking,
Modal,
Platform,
ScrollView,
StatusBar,
@@ -13,8 +11,6 @@ import {
View,
} from 'react-native';
import * as Animatable from 'react-native-animatable';
import * as RNIap from 'react-native-iap';
import QRCode from 'react-native-qrcode-generator';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {
ACCENT,
@@ -22,26 +18,29 @@ import {
COLOR_SCHEME_DARK,
COLOR_SCHEME_LIGHT,
opacity,
ph,
pv,
setColorScheme,
SIZE,
WEIGHT,
} from '../../common/common';
import {Button} from '../../components/Button';
import {PressableButton} from '../../components/PressableButton';
import Seperator from '../../components/Seperator';
import {Toast} from '../../components/Toast';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import {eSendEvent} from '../../services/eventManager';
import {eOpenLoginDialog, eResetApp} from '../../services/events';
import {
eOpenLoginDialog,
eOpenPremiumDialog,
eOpenRecoveryKeyDialog,
eResetApp,
} from '../../services/events';
import NavigationService from '../../services/NavigationService';
import {MMKV} from '../../utils/storage';
import {
db,
DDS,
hexToRGBA,
itemSkus,
RGB_Linear_Shade,
setSetting,
ToastEvent,
@@ -51,17 +50,10 @@ import {
export const Settings = ({route, navigation}) => {
const [state, dispatch] = useTracked();
const {colors, user, settings} = state;
const [key, setKey] = useState('');
const [modalVisible, setModalVisible] = useState(false);
const [subscriptions, setSubscriptions] = useState([]);
const isFocused = useIsFocused();
let subsriptionSuccessListerner;
let subsriptionErrorListener;
function changeColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
let newColors = setColorScheme(colors, accent);
StatusBar.setBarStyle(colors.night ? 'light-content' : 'dark-content');
dispatch({type: ACTIONS.THEME, colors: newColors});
}
@@ -72,43 +64,7 @@ export const Settings = ({route, navigation}) => {
}
useEffect(() => {
RNIap.getSubscriptions(itemSkus).then((subs) => {
setSubscriptions(subs);
});
subsriptionSuccessListerner = RNIap.purchaseUpdatedListener(
onSuccessfulSubscription,
);
subsriptionErrorListener = RNIap.purchaseErrorListener(onSubscriptionError);
return () => {
if (subsriptionSuccessListerner) {
subsriptionSuccessListerner.remove();
subsriptionSuccessListerner = null;
}
if (subsriptionErrorListener) {
subsriptionErrorListener.remove();
subsriptionErrorListener = null;
}
};
}, []);
const onSuccessfulSubscription = (
subscription: RNIap.SubscriptionPurchase,
) => {
const receipt = subscription.transactionReceipt;
//console.log(JSON.stringify(subscription));
if (receipt) {
console.log(JSON.stringify(subscription));
}
};
const onSubscriptionError = (error: RNIap.PurchaseError) => {
console.log(error.message, 'Error');
ToastEvent.show(error.message);
};
useEffect(() => {
console.log(user);
if (isFocused) {
dispatch({
type: ACTIONS.CONTAINER_BOTTOM_BUTTON,
@@ -122,9 +78,7 @@ export const Settings = ({route, navigation}) => {
type: null,
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({
@@ -153,6 +107,15 @@ export const Settings = ({route, navigation}) => {
}
}, [isFocused]);
const getTimeLeft = (t1, t2) => {
let d1 = new Date(Date.now());
let d2 = new Date(t2);
let diff = d2.getTime() - d1.getTime();
diff = (diff / (1000 * 3600 * 24)).toFixed(0);
return diff;
};
const SectionHeader = ({title}) => (
<Text
style={{
@@ -169,15 +132,14 @@ export const Settings = ({route, navigation}) => {
</Text>
);
const Button = ({title, tagline, customComponent, onPress, key}) => (
const CustomButton = ({title, tagline, customComponent, onPress}) => (
<PressableButton
key={key}
color="transparent"
selectedColor={colors.nav}
alpha={!colors.night ? -0.02 : 0.02}
onPress={onPress}
customStyle={{
height: 50,
minHeight: 50,
justifyContent: 'space-between',
alignItems: 'center',
paddingHorizontal: 12,
@@ -220,139 +182,6 @@ export const Settings = ({route, navigation}) => {
marginTop: Platform.OS == 'ios' ? 125 - 60 : 125 - 60,
}}
/>
<Modal
animated={true}
animationType="fade"
visible={modalVisible}
transparent={true}>
<View
style={{
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.3)',
}}>
<View
style={{
width: '100%',
backgroundColor: colors.bg,
height: '100%',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: WEIGHT.bold,
fontSize: SIZE.xl,
color: colors.pri,
marginBottom: 25,
}}>
Data Recovery Key
</Text>
<Text
style={{
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
maxWidth: '85%',
textAlign: 'center',
color: colors.pri,
}}>
<Text
style={{
color: colors.errorText,
}}>
If you lose your password, you can recover your data only using
your recovery key.{' '}
</Text>
</Text>
<Text
style={{
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
maxWidth: '85%',
textAlign: 'center',
marginTop: 25,
marginBottom: 10,
color: colors.pri,
}}>
Take a Sceenshot of QR-Code
</Text>
<QRCode value={key} size={200} bgColor="black" fgColor="white" />
<TouchableOpacity
activeOpacity={0.6}
onPress={() => {
Clipboard.setString(key);
ToastEvent.show('Recovery key copied!', 'success', 'local');
}}
style={{
flexDirection: 'row',
borderWidth: 1,
borderRadius: 5,
paddingVertical: 8,
paddingHorizontal: 10,
marginTop: 15,
alignItems: 'center',
borderColor: colors.nav,
}}>
<Text
numberOfLines={2}
style={{
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
width: '85%',
maxWidth: '85%',
paddingRight: 10,
color: colors.icon,
}}>
{key}
</Text>
<Icon color={colors.accent} size={SIZE.lg} name="clipboard" />
</TouchableOpacity>
<Text
style={{
color: colors.icon,
fontSize: 10,
width: '85%',
maxWidth: '85%',
}}>
You can also save your recovery key from app settings on any
device.
</Text>
<TouchableOpacity
onPress={() => {
setModalVisible(false);
}}
activeOpacity={opacity}
style={{
paddingVertical: pv + 5,
paddingHorizontal: ph,
borderRadius: 5,
width: '90%',
marginTop: 20,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: colors.accent,
}}>
<Text
style={{
fontFamily: WEIGHT.medium,
color: 'white',
fontSize: SIZE.sm,
}}>
I have saved the key
</Text>
</TouchableOpacity>
</View>
</View>
<Toast context="local" />
</Modal>
<ScrollView
style={{
paddingHorizontal: 0,
@@ -365,18 +194,19 @@ export const Settings = ({route, navigation}) => {
}}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'center',
alignSelf: 'center',
flexDirection: 'row',
width: '100%',
paddingVertical: pv,
marginBottom: pv,
marginTop: pv,
backgroundColor: colors.accent,
borderRadius: 5,
padding: 5,
paddingHorizontal: 12,
padding: 10,
backgroundColor: colors.shade,
}}>
<View
style={{
justifyContent: 'space-between',
alignItems: 'center',
flexDirection: 'row',
}}>
<View
style={{
@@ -384,11 +214,14 @@ export const Settings = ({route, navigation}) => {
justifyContent: 'center',
alignItems: 'center',
}}>
<Icon size={SIZE.lg} color="white" name="account-outline" />
<Icon
size={SIZE.md}
color={colors.accent}
name="account-outline"
/>
<Text
style={{
color: 'white',
color: colors.heading,
marginLeft: 5,
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
@@ -409,39 +242,56 @@ export const Settings = ({route, navigation}) => {
fontFamily: WEIGHT.regular,
fontSize: SIZE.xs,
}}>
Pro
{user.notesnook.subscription.isTrial ? 'Trial' : 'Pro'}
</Text>
</View>
</View>
<Seperator />
<View>
{user.notesnook.subscription.isTrial ? (
<Text
style={{
color:
getTimeLeft(
user.notesnook.subscription.start,
user.notesnook.subscription.expiry,
) > 5
? colors.pri
: colors.errorText,
fontFamily: WEIGHT.regular,
fontSize: SIZE.xxl,
}}>
{getTimeLeft(
user.notesnook.subscription.start,
user.notesnook.subscription.expiry,
) + ' Days Remaining'}
</Text>
) : null}
<Seperator />
<Button
onPress={() => {
eSendEvent(eOpenPremiumDialog);
}}
width="100%"
title="Get Notesnook Pro"
height={40}
/>
</View>
{
// Ad code here
}
</View>
</View>
{[
{
name: 'Data recovery key',
name: 'Save Data Recovery Key',
func: async () => {
let k = await db.user.key();
setKey(k.key);
setModalVisible(true);
eSendEvent(eOpenRecoveryKeyDialog);
},
desc:
'Generate a data recovery key to recovery your data if you lose it',
},
{
name: 'Subscription status',
func: () => {
RNIap.requestSubscription(
subscriptions[0].productId,
undefined,
undefined,
undefined,
user.Id,
)
.then((r) => {
console.log(r);
})
.catch((e) => console.log(e));
return;
},
desc: 'Current status of your subscription',
'We recommend you to get your data recovery key and store it safely. If you lose your password, you can recover your data using your recovery key.',
},
{
name: 'Logout',
@@ -449,14 +299,12 @@ export const Settings = ({route, navigation}) => {
await db.user.logout();
dispatch({type: ACTIONS.USER, user: null});
dispatch({type: ACTIONS.CLEAR_ALL});
//ToastEvent.show('Logged out, syncing disabled', 'success');
eSendEvent(eResetApp);
},
desc:
'Logout of your account, this will clear everything and reset the app.',
},
].map((item) => (
<Button
<CustomButton
key={item.name}
title={item.name}
onPress={item.func}
@@ -627,7 +475,7 @@ export const Settings = ({route, navigation}) => {
))}
</View>
<Button
<CustomButton
title="Use System Dark Mode"
tagline={
settings.useSystemTheme
@@ -664,7 +512,7 @@ export const Settings = ({route, navigation}) => {
}
/>
<Button
<CustomButton
title="Dark Mode"
tagline={colors.night ? 'Turn off dark mode' : 'Turn on dark mode'}
onPress={() => {
@@ -770,7 +618,7 @@ export const Settings = ({route, navigation}) => {
</View>
{DDS.isTab ? (
<Button
<CustomButton
title="Force portrait mode"
onPress={async () => {
await setSetting(
@@ -813,7 +661,7 @@ export const Settings = ({route, navigation}) => {
desc: 'Restore backup from your phone.',
},
].map((item) => (
<Button
<CustomButton
key={item.name}
title={item.name}
tagline={item.desc}
@@ -895,7 +743,7 @@ export const Settings = ({route, navigation}) => {
</View>
</View>
<Button
<CustomButton
title="Encrypted Backups"
tagline="Encrypt your data before backup"
onPress={async () => {
@@ -956,7 +804,7 @@ export const Settings = ({route, navigation}) => {
desc: 'You are using the latest version of our app.',
},
].map((item) => (
<Button
<CustomButton
key={item.name}
title={item.name}
tagline={item.desc}

View File

@@ -1,4 +1,4 @@
import {useIsFocused} from '@react-navigation/native';
/* import {useIsFocused} from '@react-navigation/native';
import React, {createRef, useEffect, useState} from 'react';
import {
ActivityIndicator,
@@ -759,3 +759,4 @@ export const Signup = ({route, navigation}) => {
};
export default Signup;
*/

View File

@@ -1,13 +1,13 @@
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect} from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
import {pv, SIZE, WEIGHT} from '../../common/common';
import {Placeholder} from '../../components/ListPlaceholders';
import { useIsFocused } from '@react-navigation/native';
import React, { useEffect } from 'react';
import { Text } from 'react-native';
import { SIZE, WEIGHT } from '../../common/common';
import { Placeholder } from '../../components/ListPlaceholders';
import { PressableButton } from '../../components/PressableButton';
import SimpleList from '../../components/SimpleList';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
import { useTracked } from '../../provider';
import { ACTIONS } from '../../provider/actions';
import NavigationService from '../../services/NavigationService';
import {PressableButton} from '../../components/PressableButton';
export const Tags = ({route, navigation}) => {
const [state, dispatch] = useTracked();
@@ -22,9 +22,7 @@ export const Tags = ({route, navigation}) => {
type: 'trash',
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({

View File

@@ -1,17 +1,17 @@
import { useIsFocused } from '@react-navigation/native';
import React, { useEffect } from 'react';
import { simpleDialogEvent } from '../../components/DialogManager/recievers';
import { TEMPLATE_EMPTY_TRASH } from '../../components/DialogManager/templates';
import { Placeholder } from '../../components/ListPlaceholders';
import {useIsFocused} from '@react-navigation/native';
import React, {useEffect} from 'react';
import {simpleDialogEvent} from '../../components/DialogManager/recievers';
import {TEMPLATE_EMPTY_TRASH} from '../../components/DialogManager/templates';
import {Placeholder} from '../../components/ListPlaceholders';
import SimpleList from '../../components/SimpleList';
import { NotebookItemWrapper } from '../../components/SimpleList/NotebookItemWrapper';
import { NoteItemWrapper } from '../../components/SimpleList/NoteItemWrapper';
import { useTracked } from '../../provider';
import { ACTIONS } from '../../provider/actions';
import {NotebookItemWrapper} from '../../components/SimpleList/NotebookItemWrapper';
import {NoteItemWrapper} from '../../components/SimpleList/NoteItemWrapper';
import {useTracked} from '../../provider';
import {ACTIONS} from '../../provider/actions';
export const Trash = ({route, navigation}) => {
const [state, dispatch] = useTracked();
const {colors, selectionMode, trash} = state;
const {trash} = state;
const isFocused = useIsFocused();
@@ -23,9 +23,7 @@ export const Trash = ({route, navigation}) => {
type: 'trash',
menu: true,
canGoBack: false,
route: route,
color: null,
navigation: navigation,
},
});
dispatch({