mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 11:47:54 +01:00
fix linting issues
This commit is contained in:
@@ -1,4 +1,41 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native-community',
|
||||
parser: '@babel/eslint-parser',
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true,
|
||||
'react-native/react-native': true
|
||||
},
|
||||
extends: ['eslint:recommended', 'plugin:react/recommended', 'plugin:prettier/recommended'],
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
},
|
||||
ecmaVersion: 12,
|
||||
es6: true,
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['react', 'react-native', 'prettier', 'unused-imports'],
|
||||
rules: {
|
||||
'react/display-name': 0,
|
||||
'no-unused-vars': 'off',
|
||||
'unused-imports/no-unused-vars': [
|
||||
'warn',
|
||||
{
|
||||
vars: 'all',
|
||||
varsIgnorePattern: '^_',
|
||||
args: 'after-used',
|
||||
argsIgnorePattern: '^_'
|
||||
}
|
||||
],
|
||||
'no-empty': 'off',
|
||||
'react/prop-types': 0,
|
||||
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{},
|
||||
{
|
||||
usePrettierrc: true
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
module.exports = {
|
||||
bracketSpacing: false,
|
||||
jsxBracketSameLine: true,
|
||||
singleQuote: true,
|
||||
trailingComma: 'none',
|
||||
arrowParens: 'avoid',
|
||||
bracketSpacing: true,
|
||||
jsxBracketSameLine: false,
|
||||
jsxSingleQuote: false,
|
||||
quoteProps: 'as-needed',
|
||||
singleQuote: true,
|
||||
semi: true,
|
||||
printWidth: 100,
|
||||
useTabs: false,
|
||||
tabWidth: 2,
|
||||
trailingComma: 'none'
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {hexToRGBA, RGB_Linear_Shade} from '../../utils/ColorUtils';
|
||||
import { useTracked } from '../../provider';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { hexToRGBA, RGB_Linear_Shade } from '../../utils/ColorUtils';
|
||||
import { showTooltip } from '../../utils';
|
||||
|
||||
export const ActionIcon = ({
|
||||
@@ -21,17 +21,17 @@ export const ActionIcon = ({
|
||||
disabled,
|
||||
onLongPress,
|
||||
tooltipText,
|
||||
type="gray"
|
||||
type = 'gray'
|
||||
}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return (
|
||||
<PressableButton
|
||||
testID={testID}
|
||||
onPress={onPress}
|
||||
hitSlop={{top: top, left: left, right: right, bottom: bottom}}
|
||||
onLongPress={(event) => {
|
||||
hitSlop={{ top: top, left: left, right: right, bottom: bottom }}
|
||||
onLongPress={event => {
|
||||
if (onLongPress) {
|
||||
onLongPress();
|
||||
return;
|
||||
@@ -48,14 +48,13 @@ export const ActionIcon = ({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 100,
|
||||
...customStyle,
|
||||
}}>
|
||||
...customStyle
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name={name}
|
||||
style={iconStyle}
|
||||
color={
|
||||
disabled ? RGB_Linear_Shade(-0.05, hexToRGBA(colors.nav)) : color
|
||||
}
|
||||
color={disabled ? RGB_Linear_Shade(-0.05, hexToRGBA(colors.nav)) : color}
|
||||
size={size}
|
||||
/>
|
||||
</PressableButton>
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
import React, { createRef } from 'react';
|
||||
import {
|
||||
Keyboard,
|
||||
StyleSheet, TextInput, TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { Keyboard, StyleSheet, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useMenuStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import { db } from '../../utils/database';
|
||||
import {
|
||||
eCloseAddNotebookDialog,
|
||||
eOpenAddNotebookDialog
|
||||
} from '../../utils/Events';
|
||||
import { eCloseAddNotebookDialog, eOpenAddNotebookDialog } from '../../utils/Events';
|
||||
import { ph, pv, SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
@@ -94,7 +83,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
} else {
|
||||
this.setState({
|
||||
visible: true,
|
||||
notebook:null
|
||||
notebook: null
|
||||
});
|
||||
}
|
||||
sleep(100).then(r => {
|
||||
@@ -115,7 +104,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
};
|
||||
|
||||
onDelete = index => {
|
||||
let {topics} = this.state;
|
||||
let { topics } = this.state;
|
||||
let prevTopics = topics;
|
||||
refs = [];
|
||||
prevTopics.splice(index, 1);
|
||||
@@ -145,7 +134,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
this.setState({
|
||||
loading: true
|
||||
});
|
||||
let {topics, notebook} = this.state;
|
||||
let { topics, notebook } = this.state;
|
||||
|
||||
if (!this.title || this.title?.trim().length === 0) {
|
||||
ToastEvent.show({
|
||||
@@ -176,9 +165,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
|
||||
if (notebook) {
|
||||
if (this.topicsToDelete?.length > 0) {
|
||||
await db.notebooks
|
||||
.notebook(toEdit.id)
|
||||
.topics.delete(...this.topicsToDelete);
|
||||
await db.notebooks.notebook(toEdit.id).topics.delete(...this.topicsToDelete);
|
||||
toEdit = db.notebooks.notebook(toEdit.id).data;
|
||||
}
|
||||
|
||||
@@ -189,7 +176,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
});
|
||||
|
||||
let nextTopics = toEdit.topics.map((topic, index) => {
|
||||
let copy = {...topic};
|
||||
let copy = { ...topic };
|
||||
copy.title = prevTopics[index];
|
||||
return copy;
|
||||
});
|
||||
@@ -206,7 +193,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
title: this.title,
|
||||
description: this.description,
|
||||
topics: prevTopics,
|
||||
id:null
|
||||
id: null
|
||||
});
|
||||
}
|
||||
useMenuStore.getState().setMenuPins();
|
||||
@@ -224,9 +211,8 @@ export class AddNotebookDialog extends React.Component {
|
||||
onSubmit = (forward = true) => {
|
||||
this.hiddenInput.current?.focus();
|
||||
let willFocus = true;
|
||||
let {topics} = this.state;
|
||||
if (!this.currentInputValue || this.currentInputValue?.trim().length === 0)
|
||||
return;
|
||||
let { topics } = this.state;
|
||||
if (!this.currentInputValue || this.currentInputValue?.trim().length === 0) return;
|
||||
|
||||
let prevTopics = [...topics];
|
||||
if (this.prevItem === null) {
|
||||
@@ -235,7 +221,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
topics: prevTopics
|
||||
});
|
||||
setTimeout(() => {
|
||||
this.listRef.scrollToEnd({animated: true});
|
||||
this.listRef.scrollToEnd({ animated: true });
|
||||
}, 30);
|
||||
this.currentInputValue = null;
|
||||
} else {
|
||||
@@ -259,7 +245,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
|
||||
if (forward) {
|
||||
setTimeout(() => {
|
||||
this.listRef.scrollToEnd({animated: true});
|
||||
this.listRef.scrollToEnd({ animated: true });
|
||||
}, 30);
|
||||
}
|
||||
}
|
||||
@@ -270,8 +256,8 @@ export class AddNotebookDialog extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {colors} = this.props;
|
||||
const {topics, visible, topicInputFocused, notebook} = this.state;
|
||||
const { colors } = this.props;
|
||||
const { topics, visible, topicInputFocused, notebook } = this.state;
|
||||
if (!visible) return null;
|
||||
return (
|
||||
<SheetWrapper
|
||||
@@ -293,13 +279,15 @@ export class AddNotebookDialog extends React.Component {
|
||||
});
|
||||
}}
|
||||
statusBarTranslucent={false}
|
||||
onRequestClose={this.close}>
|
||||
onRequestClose={this.close}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
maxHeight: DDS.isTab ? '90%' : '100%',
|
||||
borderRadius: DDS.isTab ? 5 : 0,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
ref={this.hiddenInput}
|
||||
style={{
|
||||
@@ -311,11 +299,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
blurOnSubmit={false}
|
||||
/>
|
||||
<DialogHeader
|
||||
title={
|
||||
notebook && notebook.dateCreated
|
||||
? 'Edit Notebook'
|
||||
: 'New Notebook'
|
||||
}
|
||||
title={notebook && notebook.dateCreated ? 'Edit Notebook' : 'New Notebook'}
|
||||
paragraph={
|
||||
notebook && notebook.dateCreated
|
||||
? 'You are editing ' + this.title + ' notebook.'
|
||||
@@ -392,8 +376,8 @@ export class AddNotebookDialog extends React.Component {
|
||||
}}
|
||||
keyboardShouldPersistTaps="always"
|
||||
keyboardDismissMode="interactive"
|
||||
ListFooterComponent={<View style={{height: 50}} />}
|
||||
renderItem={({item, index}) => (
|
||||
ListFooterComponent={<View style={{ height: 50 }} />}
|
||||
renderItem={({ item, index }) => (
|
||||
<TopicItem
|
||||
item={item}
|
||||
onPress={(item, index) => {
|
||||
@@ -419,11 +403,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
width="100%"
|
||||
height={50}
|
||||
fontSize={SIZE.md}
|
||||
title={
|
||||
notebook && notebook.dateCreated
|
||||
? 'Save changes'
|
||||
: 'Create notebook'
|
||||
}
|
||||
title={notebook && notebook.dateCreated ? 'Save changes' : 'Create notebook'}
|
||||
type="accent"
|
||||
onPress={this.addNewNotebook}
|
||||
/>
|
||||
@@ -443,7 +423,7 @@ export class AddNotebookDialog extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const TopicItem = ({item, index, colors, onPress, onDelete}) => {
|
||||
const TopicItem = ({ item, index, colors, onPress, onDelete }) => {
|
||||
const topicRef = ref => (refs[index] = ref);
|
||||
|
||||
return (
|
||||
@@ -455,7 +435,8 @@ const TopicItem = ({item, index, colors, onPress, onDelete}) => {
|
||||
backgroundColor: colors.nav,
|
||||
borderRadius: 5,
|
||||
marginVertical: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
width: '80%',
|
||||
@@ -489,7 +470,8 @@ const TopicItem = ({item, index, colors, onPress, onDelete}) => {
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
onPress={() => {
|
||||
onPress(item, index);
|
||||
|
||||
@@ -1,27 +1,19 @@
|
||||
import React, {createRef} from 'react';
|
||||
import {Keyboard, LayoutAnimation, UIManager, View} from 'react-native';
|
||||
import {
|
||||
Transition,
|
||||
Transitioning,
|
||||
TransitioningView
|
||||
} from 'react-native-reanimated';
|
||||
import {useMenuStore} from '../../provider/stores';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import React, { createRef } from 'react';
|
||||
import { Keyboard, LayoutAnimation, UIManager, View } from 'react-native';
|
||||
import { Transition, Transitioning, TransitioningView } from 'react-native-reanimated';
|
||||
import { useMenuStore } from '../../provider/stores';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {eCloseAddTopicDialog, eOpenAddTopicDialog} from '../../utils/Events';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eCloseAddTopicDialog, eOpenAddTopicDialog } from '../../utils/Events';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import DialogButtons from '../Dialog/dialog-buttons';
|
||||
import DialogContainer from '../Dialog/dialog-container';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Input from '../Input';
|
||||
import Seperator from '../Seperator';
|
||||
import {Toast} from '../Toast';
|
||||
import { Toast } from '../Toast';
|
||||
|
||||
export class AddTopicDialog extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -41,14 +33,14 @@ export class AddTopicDialog extends React.Component {
|
||||
|
||||
addNewTopic = async () => {
|
||||
try {
|
||||
this.setState({loading: true});
|
||||
this.setState({ loading: true });
|
||||
if (!this.title || this.title?.trim() === '') {
|
||||
ToastEvent.show({
|
||||
heading: 'Topic title is required',
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
this.setState({loading: false});
|
||||
this.setState({ loading: false });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -60,7 +52,7 @@ export class AddTopicDialog extends React.Component {
|
||||
|
||||
await db.notebooks.notebook(topic.notebookId).topics.add(topic);
|
||||
}
|
||||
this.setState({loading: false});
|
||||
this.setState({ loading: false });
|
||||
this.close();
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.Notebooks,
|
||||
@@ -80,7 +72,7 @@ export class AddTopicDialog extends React.Component {
|
||||
eUnSubscribeEvent(eCloseAddTopicDialog, this.close);
|
||||
}
|
||||
|
||||
open = async ({notebookId, toEdit}) => {
|
||||
open = async ({ notebookId, toEdit }) => {
|
||||
let id = notebookId;
|
||||
if (id) {
|
||||
this.notebook = await db.notebooks.notebook(id).data;
|
||||
@@ -105,7 +97,7 @@ export class AddTopicDialog extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {visible} = this.state;
|
||||
const { visible } = this.state;
|
||||
if (!visible) return null;
|
||||
return (
|
||||
<BaseDialog
|
||||
@@ -123,15 +115,14 @@ export class AddTopicDialog extends React.Component {
|
||||
bounce={false}
|
||||
statusBarTranslucent={false}
|
||||
visible={true}
|
||||
onRequestClose={this.close}>
|
||||
onRequestClose={this.close}
|
||||
>
|
||||
<DialogContainer>
|
||||
<DialogHeader
|
||||
icon="book-outline"
|
||||
title={this.toEdit ? 'Edit topic' : 'New topic'}
|
||||
paragraph={
|
||||
this.toEdit
|
||||
? 'Edit title of the topic'
|
||||
: 'Add a new topic in ' + this.notebook.title
|
||||
this.toEdit ? 'Edit title of the topic' : 'Add a new topic in ' + this.notebook.title
|
||||
}
|
||||
padding={12}
|
||||
/>
|
||||
@@ -139,7 +130,8 @@ export class AddTopicDialog extends React.Component {
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
fwdRef={this.titleRef}
|
||||
onChangeText={value => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import {FlatList, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMessageStore, useSelectionStore} from '../../provider/stores';
|
||||
import {Button} from '../Button';
|
||||
import {allowedOnPlatform, renderItem} from './functions';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMessageStore, useSelectionStore } from '../../provider/stores';
|
||||
import { Button } from '../Button';
|
||||
import { allowedOnPlatform, renderItem } from './functions';
|
||||
|
||||
export const Announcement = ({color}) => {
|
||||
export const Announcement = ({ color }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
const announcements = useMessageStore(state => state.announcements);
|
||||
@@ -18,14 +18,16 @@ export const Announcement = ({color}) => {
|
||||
style={{
|
||||
backgroundColor: colors.bg,
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
paddingVertical: 12,
|
||||
width: '100%',
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="errorShade"
|
||||
icon="close"
|
||||
@@ -48,11 +50,9 @@ export const Announcement = ({color}) => {
|
||||
width: '100%',
|
||||
marginTop: 15
|
||||
}}
|
||||
data={announcement?.body.filter(item =>
|
||||
allowedOnPlatform(item.platforms)
|
||||
)}
|
||||
renderItem={({item, index}) =>
|
||||
renderItem({item: item, index: index, color: colors[color],inline:true})
|
||||
data={announcement?.body.filter(item => allowedOnPlatform(item.platforms))}
|
||||
renderItem={({ item, index }) =>
|
||||
renderItem({ item: item, index: index, color: colors[color], inline: true })
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -3,8 +3,7 @@ import { useTracked } from '../../provider';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
|
||||
export const Body = ({text, style = {}}) => {
|
||||
export const Body = ({ text, style = {} }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -13,8 +12,9 @@ export const Body = ({text, style = {}}) => {
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Paragraph>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent, presentSheet} from '../../services/EventManager';
|
||||
import {eCloseAnnouncementDialog} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSendEvent, presentSheet } from '../../services/EventManager';
|
||||
import { eCloseAnnouncementDialog } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import SettingsBackupAndRestore from '../../views/Settings/backup-restore';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import GeneralSheet from '../GeneralSheet';
|
||||
import {PricingPlans} from '../Premium/pricing-plans';
|
||||
import {allowedOnPlatform, getStyle} from './functions';
|
||||
import { PricingPlans } from '../Premium/pricing-plans';
|
||||
import { allowedOnPlatform, getStyle } from './functions';
|
||||
|
||||
export const Cta = ({actions, style = {}, color, inline}) => {
|
||||
export const Cta = ({ actions, style = {}, color, inline }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
let buttons = actions.filter(item => allowedOnPlatform(item.platforms)) || [];
|
||||
@@ -51,7 +51,8 @@ export const Cta = ({actions, style = {}, color, inline}) => {
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<GeneralSheet context="premium_cta" />
|
||||
{buttons.length > 0 &&
|
||||
buttons.slice(0, 1).map(item => (
|
||||
|
||||
@@ -4,8 +4,7 @@ import { SIZE } from '../../utils/SizeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
|
||||
export const Description = ({text, style = {}}) => {
|
||||
export const Description = ({ text, style = {} }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
return (
|
||||
@@ -14,7 +13,8 @@ export const Description = ({text, style = {}}) => {
|
||||
style={{
|
||||
marginHorizontal: 12,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Paragraph>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {allowedPlatforms} from '../../provider/stores';
|
||||
import {ProFeatures} from '../ResultDialog/pro-features';
|
||||
import {Body} from './body';
|
||||
import {Cta} from './cta';
|
||||
import {Description} from './description';
|
||||
import {List} from './list';
|
||||
import {Photo} from './photo';
|
||||
import {SubHeading} from './subheading';
|
||||
import {Title} from './title';
|
||||
import { View } from 'react-native';
|
||||
import { allowedPlatforms } from '../../provider/stores';
|
||||
import { ProFeatures } from '../ResultDialog/pro-features';
|
||||
import { Body } from './body';
|
||||
import { Cta } from './cta';
|
||||
import { Description } from './description';
|
||||
import { List } from './list';
|
||||
import { Photo } from './photo';
|
||||
import { SubHeading } from './subheading';
|
||||
import { Title } from './title';
|
||||
|
||||
export function allowedOnPlatform(platforms) {
|
||||
if (!platforms) return true;
|
||||
@@ -37,7 +37,8 @@ const Features = () => {
|
||||
paddingHorizontal: 12,
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ProFeatures />
|
||||
</View>
|
||||
);
|
||||
@@ -47,7 +48,7 @@ const renderItems = {
|
||||
title: Title,
|
||||
description: Description,
|
||||
body: Body,
|
||||
text:Body,
|
||||
text: Body,
|
||||
image: Photo,
|
||||
list: List,
|
||||
subheading: SubHeading,
|
||||
@@ -55,8 +56,16 @@ const renderItems = {
|
||||
callToActions: Cta
|
||||
};
|
||||
|
||||
export const renderItem = ({item, index, color,inline}) => {
|
||||
const Item = renderItems[item.type] || Fragment
|
||||
export const renderItem = ({ item, index, color, inline }) => {
|
||||
const Item = renderItems[item.type] || Fragment;
|
||||
|
||||
return <Item key={item.text || item.src || item.type} {...item} index={index} color={color} inline={inline} />;
|
||||
return (
|
||||
<Item
|
||||
key={item.text || item.src || item.type}
|
||||
{...item}
|
||||
index={index}
|
||||
color={color}
|
||||
inline={inline}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {FlatList, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMessageStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import {
|
||||
eCloseAnnouncementDialog,
|
||||
eOpenAnnouncementDialog
|
||||
} from '../../utils/Events';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMessageStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { eCloseAnnouncementDialog, eOpenAnnouncementDialog } from '../../utils/Events';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import {allowedOnPlatform, renderItem} from './functions';
|
||||
import { allowedOnPlatform, renderItem } from './functions';
|
||||
|
||||
export const AnnouncementDialog = () => {
|
||||
const [state] = useTracked();
|
||||
@@ -46,7 +43,8 @@ export const AnnouncementDialog = () => {
|
||||
centered={false}
|
||||
bottom={true}
|
||||
onRequestClose={close}
|
||||
visible={visible}>
|
||||
visible={visible}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: DDS.isTab ? 600 : '100%',
|
||||
@@ -55,7 +53,8 @@ export const AnnouncementDialog = () => {
|
||||
borderRadius: DDS.isTab ? 10 : 0,
|
||||
overflow: 'hidden',
|
||||
marginBottom: DDS.isTab ? 20 : 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<FlatList
|
||||
style={{
|
||||
width: '100%'
|
||||
|
||||
@@ -5,28 +5,32 @@ import { useTracked } from '../../provider';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
export const List = ({items, listType, style = {}}) => {
|
||||
export const List = ({ items, listType, style = {} }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
paddingLeft: listType === 'ordered' ? 25 : 25,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
<View
|
||||
key={item.text}
|
||||
style={{
|
||||
paddingVertical: 6,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{listType === 'ordered' ? (
|
||||
<Paragraph
|
||||
style={{
|
||||
marginRight: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{index + 1}.
|
||||
</Paragraph>
|
||||
) : (
|
||||
|
||||
@@ -2,11 +2,10 @@ import React from 'react';
|
||||
import { Image } from 'react-native';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
|
||||
export const Photo = ({src, style = {}}) => {
|
||||
return src ?(
|
||||
export const Photo = ({ src, style = {} }) => {
|
||||
return src ? (
|
||||
<Image
|
||||
source={{uri: src}}
|
||||
source={{ uri: src }}
|
||||
resizeMode="cover"
|
||||
style={{
|
||||
width: '100%',
|
||||
@@ -15,5 +14,5 @@ export const Photo = ({src, style = {}}) => {
|
||||
...getStyle(style)
|
||||
}}
|
||||
/>
|
||||
) : null
|
||||
};
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -4,8 +4,7 @@ import { SIZE } from '../../utils/SizeUtils';
|
||||
import Heading from '../Typography/Heading';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
|
||||
export const SubHeading = ({text, style = {}}) => {
|
||||
export const SubHeading = ({ text, style = {} }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -16,7 +15,8 @@ export const SubHeading = ({text, style = {}}) => {
|
||||
marginHorizontal: 12,
|
||||
marginTop: 12,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Heading>
|
||||
);
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useTracked } from '../../provider';
|
||||
import Heading from '../Typography/Heading';
|
||||
import { getStyle } from './functions';
|
||||
|
||||
export const Title = ({text, style = {}}) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
return (
|
||||
<Heading
|
||||
style={{
|
||||
marginHorizontal: 12,
|
||||
marginTop: 12,
|
||||
...getStyle(style)
|
||||
}}>
|
||||
{text}
|
||||
</Heading>
|
||||
);
|
||||
};
|
||||
export const Title = ({ text, style = {} }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
return (
|
||||
<Heading
|
||||
style={{
|
||||
marginHorizontal: 12,
|
||||
marginTop: 12,
|
||||
...getStyle(style)
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</Heading>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {Appearance, Linking, Platform, SafeAreaView, View} from 'react-native';
|
||||
import Animated, {Easing} from 'react-native-reanimated';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Appearance, Linking, Platform, SafeAreaView, View } from 'react-native';
|
||||
import Animated, { Easing } from 'react-native-reanimated';
|
||||
import AnimatedProgress from 'react-native-reanimated-progress-bar';
|
||||
import {useTracked} from '../../provider';
|
||||
import { useTracked } from '../../provider';
|
||||
import {
|
||||
useFavoriteStore,
|
||||
useMessageStore,
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
} from '../../provider/stores';
|
||||
import Backup from '../../services/Backup';
|
||||
import BiometricService from '../../services/BiometricService';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
@@ -21,34 +21,30 @@ import {
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import PremiumService from '../../services/PremiumService';
|
||||
import {editing, STORE_LINK} from '../../utils';
|
||||
import {COLOR_SCHEME_DARK, COLOR_SCHEME_LIGHT} from '../../utils/Colors';
|
||||
import {db} from '../../utils/database';
|
||||
import {
|
||||
eOpenAnnouncementDialog,
|
||||
eOpenLoginDialog,
|
||||
eOpenRateDialog
|
||||
} from '../../utils/Events';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {tabBarRef} from '../../utils/Refs';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { editing, STORE_LINK } from '../../utils';
|
||||
import { COLOR_SCHEME_DARK, COLOR_SCHEME_LIGHT } from '../../utils/Colors';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenAnnouncementDialog, eOpenLoginDialog, eOpenRateDialog } from '../../utils/Events';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { tabBarRef } from '../../utils/Refs';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import SettingsBackupAndRestore from '../../views/Settings/backup-restore';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import Input from '../Input';
|
||||
import Seperator from '../Seperator';
|
||||
import SplashScreen from '../SplashScreen';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {checkVersion} from 'react-native-check-version';
|
||||
import {Placeholder, SvgToPngView} from '../ListPlaceholders';
|
||||
import {Update} from '../Update';
|
||||
import {setRateAppMessage} from '../../services/Message';
|
||||
import { checkVersion } from 'react-native-check-version';
|
||||
import { Placeholder, SvgToPngView } from '../ListPlaceholders';
|
||||
import { Update } from '../Update';
|
||||
import { setRateAppMessage } from '../../services/Message';
|
||||
|
||||
let passwordValue = null;
|
||||
let didVerifyUser = false;
|
||||
const opacityV = new Animated.Value(1);
|
||||
const AppLoader = ({onLoad}) => {
|
||||
const AppLoader = ({ onLoad }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -172,10 +168,7 @@ const AppLoader = ({onLoad}) => {
|
||||
const checkNeedsBackup = async () => {
|
||||
let settingsStore = useSettingStore.getState();
|
||||
let askForBackup = await MMKV.getItem('askForBackup');
|
||||
if (
|
||||
settingsStore.settings.reminder === 'off' ||
|
||||
!settingsStore.settings.reminder
|
||||
) {
|
||||
if (settingsStore.settings.reminder === 'off' || !settingsStore.settings.reminder) {
|
||||
askForBackup = JSON.parse(askForBackup);
|
||||
if (askForBackup?.timestamp < Date.now()) {
|
||||
presentSheet({
|
||||
@@ -215,10 +208,7 @@ const AppLoader = ({onLoad}) => {
|
||||
});
|
||||
return;
|
||||
}
|
||||
let verified = await BiometricService.validateUser(
|
||||
'Unlock to access your notes',
|
||||
''
|
||||
);
|
||||
let verified = await BiometricService.validateUser('Unlock to access your notes', '');
|
||||
if (verified) {
|
||||
didVerifyUser = true;
|
||||
setVerifyUser(false);
|
||||
@@ -241,46 +231,40 @@ const AppLoader = ({onLoad}) => {
|
||||
return loading ? (
|
||||
<Animated.View
|
||||
style={{
|
||||
backgroundColor:
|
||||
Appearance.getColorScheme() === 'dark'
|
||||
? COLOR_SCHEME_DARK.bg
|
||||
: colors.bg,
|
||||
backgroundColor: Appearance.getColorScheme() === 'dark' ? COLOR_SCHEME_DARK.bg : colors.bg,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
position: 'absolute',
|
||||
zIndex: 999,
|
||||
borderRadius: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Animated.View
|
||||
style={{
|
||||
backgroundColor:
|
||||
Appearance.getColorScheme() === 'dark'
|
||||
? COLOR_SCHEME_DARK.bg
|
||||
: colors.bg,
|
||||
Appearance.getColorScheme() === 'dark' ? COLOR_SCHEME_DARK.bg : colors.bg,
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderRadius: 10,
|
||||
opacity: opacityV
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{verifyUser ? (
|
||||
<SafeAreaView
|
||||
style={{
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
width:
|
||||
deviceMode !== 'mobile'
|
||||
? '50%'
|
||||
: Platform.OS == 'ios'
|
||||
? '95%'
|
||||
: '100%',
|
||||
width: deviceMode !== 'mobile' ? '50%' : Platform.OS == 'ios' ? '95%' : '100%',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
style={{
|
||||
alignSelf: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Verify your identity
|
||||
</Heading>
|
||||
|
||||
@@ -289,9 +273,10 @@ const AppLoader = ({onLoad}) => {
|
||||
<Paragraph
|
||||
style={{
|
||||
alignSelf: 'center'
|
||||
}}>
|
||||
To keep your notes secure, please enter password of the
|
||||
account you are logged in to.
|
||||
}}
|
||||
>
|
||||
To keep your notes secure, please enter password of the account you are logged in
|
||||
to.
|
||||
</Paragraph>
|
||||
<Seperator />
|
||||
<Input
|
||||
@@ -317,9 +302,9 @@ const AppLoader = ({onLoad}) => {
|
||||
<Paragraph
|
||||
style={{
|
||||
alignSelf: 'center'
|
||||
}}>
|
||||
To keep your notes secure, please unlock app the with
|
||||
biometrics.
|
||||
}}
|
||||
>
|
||||
To keep your notes secure, please unlock app the with biometrics.
|
||||
</Paragraph>
|
||||
<Seperator />
|
||||
</>
|
||||
@@ -341,7 +326,8 @@ const AppLoader = ({onLoad}) => {
|
||||
height: 10,
|
||||
flexDirection: 'row',
|
||||
width: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<AnimatedProgress
|
||||
style={{
|
||||
backgroundColor:
|
||||
|
||||
@@ -5,15 +5,9 @@ import * as Progress from 'react-native-progress';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useAttachmentStore } from '../../provider/stores';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { db } from '../../utils/database';
|
||||
import {
|
||||
eCloseAttachmentDialog,
|
||||
eOpenAttachmentsDialog
|
||||
} from '../../utils/Events';
|
||||
import { eCloseAttachmentDialog, eOpenAttachmentsDialog } from '../../utils/Events';
|
||||
import filesystem from '../../utils/filesystem';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
@@ -41,7 +35,7 @@ export const AttachmentDialog = () => {
|
||||
const open = item => {
|
||||
setNote(item);
|
||||
setVisible(true);
|
||||
let _attachments = db.attachments.ofNote(item.id, "all");
|
||||
let _attachments = db.attachments.ofNote(item.id, 'all');
|
||||
setAttachments(_attachments);
|
||||
};
|
||||
|
||||
@@ -62,13 +56,15 @@ export const AttachmentDialog = () => {
|
||||
fwdRef={actionSheetRef}
|
||||
onClose={async () => {
|
||||
setVisible(false);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader title="Attachments" />
|
||||
<FlatList
|
||||
nestedScrollEnabled
|
||||
@@ -85,13 +81,14 @@ export const AttachmentDialog = () => {
|
||||
height: 150,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="attachment" size={60} color={colors.icon} />
|
||||
<Paragraph>No attachments on this note</Paragraph>
|
||||
</View>
|
||||
}
|
||||
data={attachments}
|
||||
renderItem={({item, index}) => (
|
||||
renderItem={({ item, index }) => (
|
||||
<Attachment attachment={item} note={note} setNote={setNote} />
|
||||
)}
|
||||
/>
|
||||
@@ -102,7 +99,8 @@ export const AttachmentDialog = () => {
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="shield-key-outline" size={SIZE.xs} color={colors.icon} />
|
||||
{' '}All attachments are end-to-end encrypted.
|
||||
</Paragraph>
|
||||
@@ -128,7 +126,7 @@ function getFileExtension(filename) {
|
||||
return ext == null ? '' : ext[1];
|
||||
}
|
||||
|
||||
export const Attachment = ({attachment, encryption}) => {
|
||||
export const Attachment = ({ attachment, encryption }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
const progress = useAttachmentStore(state => state.progress);
|
||||
@@ -149,7 +147,7 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
useAttachmentStore.getState().remove(attachment.metadata.hash);
|
||||
return;
|
||||
}
|
||||
filesystem.downloadAttachment(attachment.metadata.hash,false);
|
||||
filesystem.downloadAttachment(attachment.metadata.hash, false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -182,20 +180,23 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
borderRadius: 5,
|
||||
backgroundColor: colors.nav
|
||||
}}
|
||||
type="grayBg">
|
||||
type="grayBg"
|
||||
>
|
||||
<GeneralSheet context={attachment.metadata.hash} />
|
||||
<View
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginLeft: -5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="file" size={SIZE.xxxl} color={colors.icon} />
|
||||
|
||||
<Paragraph
|
||||
@@ -204,7 +205,8 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
color={colors.light}
|
||||
style={{
|
||||
position: 'absolute'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{getFileExtension(attachment.metadata.filename).toUpperCase()}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -213,7 +215,8 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
marginLeft: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={SIZE.sm - 1}
|
||||
style={{
|
||||
@@ -222,18 +225,15 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
}}
|
||||
numberOfLines={1}
|
||||
lineBreakMode="middle"
|
||||
color={colors.pri}>
|
||||
color={colors.pri}
|
||||
>
|
||||
{attachment.metadata.filename}
|
||||
</Paragraph>
|
||||
|
||||
|
||||
<Paragraph color={colors.icon} size={SIZE.xs}>
|
||||
{formatBytes(attachment.length)}{' '}
|
||||
{currentProgress?.type
|
||||
? '(' + currentProgress.type + 'ing - tap to cancel)'
|
||||
: ''}
|
||||
{currentProgress?.type ? '(' + currentProgress.type + 'ing - tap to cancel)' : ''}
|
||||
</Paragraph>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -250,7 +250,8 @@ export const Attachment = ({attachment, encryption}) => {
|
||||
marginLeft: 5,
|
||||
marginTop: 5,
|
||||
marginRight: -5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Progress.Circle
|
||||
size={SIZE.xxl}
|
||||
progress={
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import {ActivityIndicator} from 'react-native';
|
||||
import { ActivityIndicator } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {BUTTON_TYPES, showTooltip} from '../../utils';
|
||||
import {ph, SIZE} from '../../utils/SizeUtils';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { useTracked } from '../../provider';
|
||||
import { BUTTON_TYPES, showTooltip } from '../../utils';
|
||||
import { ph, SIZE } from '../../utils/SizeUtils';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
@@ -36,7 +36,7 @@ export const Button = ({
|
||||
iconColor
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const textColor = buttonType.text
|
||||
? buttonType.text
|
||||
@@ -45,8 +45,7 @@ export const Button = ({
|
||||
? BUTTON_TYPES[type](accentColor, accentText).text
|
||||
: BUTTON_TYPES[type].text
|
||||
];
|
||||
const Component = bold ? Heading : Paragraph
|
||||
|
||||
const Component = bold ? Heading : Paragraph;
|
||||
|
||||
return (
|
||||
<PressableButton
|
||||
@@ -80,7 +79,8 @@ export const Button = ({
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
...style
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{loading ? <ActivityIndicator color={textColor} size={fontSize + 4} /> : null}
|
||||
{icon && !loading && iconPosition === 'left' ? (
|
||||
<Icon
|
||||
@@ -88,7 +88,6 @@ export const Button = ({
|
||||
style={{
|
||||
marginRight: 0
|
||||
}}
|
||||
|
||||
color={iconColor || buttonType.text || textColor}
|
||||
size={iconSize}
|
||||
/>
|
||||
@@ -105,7 +104,8 @@ export const Button = ({
|
||||
marginRight: icon || (loading && iconPosition === 'right') ? 5 : 0
|
||||
},
|
||||
textStyle
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
{title}
|
||||
</Component>
|
||||
)}
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import {Keyboard, Platform, View} from 'react-native';
|
||||
import Animated, {Easing, sub} from 'react-native-reanimated';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Keyboard, Platform, View } from 'react-native';
|
||||
import Animated, { Easing, sub } from 'react-native-reanimated';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useSettingStore} from '../../provider/stores';
|
||||
import {
|
||||
editing,
|
||||
getElevation,
|
||||
showTooltip,
|
||||
TOOLTIP_POSITIONS,
|
||||
} from '../../utils';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useSettingStore } from '../../provider/stores';
|
||||
import { editing, getElevation, showTooltip, TOOLTIP_POSITIONS } from '../../utils';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
|
||||
const translateY = new Animated.Value(0);
|
||||
export const ContainerBottomButton = ({
|
||||
title,
|
||||
onPress,
|
||||
color = 'accent',
|
||||
shouldShow = false,
|
||||
}) => {
|
||||
export const ContainerBottomButton = ({ title, onPress, color = 'accent', shouldShow = false }) => {
|
||||
const insets = useSafeAreaInsets();
|
||||
const deviceMode = useSettingStore(state => state.deviceMode);
|
||||
|
||||
@@ -28,7 +18,7 @@ export const ContainerBottomButton = ({
|
||||
Animated.timing(translateY, {
|
||||
toValue: translate,
|
||||
duration: 250,
|
||||
easing: Easing.elastic(1),
|
||||
easing: Easing.elastic(1)
|
||||
}).start();
|
||||
}
|
||||
|
||||
@@ -45,8 +35,8 @@ export const ContainerBottomButton = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
let sub1 = Keyboard.addListener('keyboardDidShow', onKeyboardShow);
|
||||
let sub2 = Keyboard.addListener('keyboardDidHide', onKeyboardHide);
|
||||
let sub1 = Keyboard.addListener('keyboardDidShow', onKeyboardShow);
|
||||
let sub2 = Keyboard.addListener('keyboardDidHide', onKeyboardHide);
|
||||
return () => {
|
||||
sub1?.remove();
|
||||
sub2?.remove();
|
||||
@@ -67,13 +57,14 @@ export const ContainerBottomButton = ({
|
||||
zIndex: 10,
|
||||
transform: [
|
||||
{
|
||||
translateY: translateY,
|
||||
translateY: translateY
|
||||
},
|
||||
{
|
||||
translateX: translateY,
|
||||
},
|
||||
],
|
||||
}}>
|
||||
translateX: translateY
|
||||
}
|
||||
]
|
||||
}}
|
||||
>
|
||||
<PressableButton
|
||||
testID={notesnook.buttons.add}
|
||||
type="accent"
|
||||
@@ -81,20 +72,21 @@ export const ContainerBottomButton = ({
|
||||
accentText="light"
|
||||
customStyle={{
|
||||
...getElevation(5),
|
||||
borderRadius: 100,
|
||||
borderRadius: 100
|
||||
}}
|
||||
onLongPress={event => {
|
||||
showTooltip(event, title, TOOLTIP_POSITIONS.LEFT);
|
||||
}}
|
||||
onPress={onPress}>
|
||||
onPress={onPress}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '100%',
|
||||
height: normalize(60),
|
||||
width: normalize(60),
|
||||
}}>
|
||||
width: normalize(60)
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name={title === 'Clear all trash' ? 'delete' : 'plus'}
|
||||
color="white"
|
||||
|
||||
@@ -3,9 +3,9 @@ import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSelectionStore } from '../../provider/stores';
|
||||
|
||||
export const ContainerTopSection = ({children}) => {
|
||||
export const ContainerTopSection = ({ children }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const selectionMode = useSelectionStore(state => state.selectionMode);
|
||||
|
||||
return !selectionMode ? (
|
||||
@@ -13,9 +13,10 @@ export const ContainerTopSection = ({children}) => {
|
||||
style={{
|
||||
backgroundColor: colors.bg,
|
||||
width: '100%',
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</View>
|
||||
) : null
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -2,25 +2,27 @@ import React from 'react';
|
||||
import { KeyboardAvoidingView, Platform, SafeAreaView } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import useIsFloatingKeyboard from '../../utils/use-is-floating-keyboard';
|
||||
export const Container = ({children}) => {
|
||||
export const Container = ({ children }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors, } = state;
|
||||
const { colors } = state;
|
||||
const floating = useIsFloatingKeyboard();
|
||||
return (
|
||||
<KeyboardAvoidingView behavior="padding" enabled={Platform.OS === 'ios' && !floating }
|
||||
<KeyboardAvoidingView
|
||||
behavior="padding"
|
||||
enabled={Platform.OS === 'ios' && !floating}
|
||||
style={{
|
||||
backgroundColor:colors.bg,
|
||||
width:"100%",
|
||||
height:"100%"
|
||||
backgroundColor: colors.bg,
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}}
|
||||
>
|
||||
<SafeAreaView
|
||||
style={{
|
||||
height: '100%',
|
||||
backgroundColor:colors.bg,
|
||||
overflow:"hidden",
|
||||
}}>
|
||||
|
||||
backgroundColor: colors.bg,
|
||||
overflow: 'hidden'
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</SafeAreaView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, {Component, createRef} from 'react';
|
||||
import {Platform} from 'react-native';
|
||||
import {Keyboard} from 'react-native';
|
||||
import {FlatList, TextInput, View} from 'react-native';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {editing} from '../../utils';
|
||||
import React, { Component, createRef } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import { Keyboard } from 'react-native';
|
||||
import { FlatList, TextInput, View } from 'react-native';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { editing } from '../../utils';
|
||||
|
||||
export default class CustomTabs extends Component {
|
||||
constructor(props) {
|
||||
@@ -22,7 +22,7 @@ export default class CustomTabs extends Component {
|
||||
this.lastOffset = this.props.offsets.a;
|
||||
}
|
||||
|
||||
renderItem = ({item, index}) => this.props.items[index];
|
||||
renderItem = ({ item, index }) => this.props.items[index];
|
||||
|
||||
onMoveShouldSetResponder = event => {
|
||||
if (this.responderAllowedScroll) return;
|
||||
@@ -69,8 +69,7 @@ export default class CustomTabs extends Component {
|
||||
this.currentDrawerState = true;
|
||||
this.goToIndex(0);
|
||||
}
|
||||
this.props.onDrawerStateChange &&
|
||||
this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
this.props.onDrawerStateChange && this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,8 +77,7 @@ export default class CustomTabs extends Component {
|
||||
if (this.page === 0) {
|
||||
this.goToIndex(1);
|
||||
this.currentDrawerState = false;
|
||||
this.props.onDrawerStateChange &&
|
||||
this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
this.props.onDrawerStateChange && this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -151,11 +149,7 @@ export default class CustomTabs extends Component {
|
||||
this.scrollTimeout = null;
|
||||
}
|
||||
this.scrollTimeout = setTimeout(() => {
|
||||
if (
|
||||
this.scrollOffset !== this.props.offsets.a &&
|
||||
this.page === 1 &&
|
||||
!this.scrollEnabled
|
||||
) {
|
||||
if (this.scrollOffset !== this.props.offsets.a && this.page === 1 && !this.scrollEnabled) {
|
||||
this.goToIndex(2, false);
|
||||
}
|
||||
}, 300);
|
||||
@@ -174,7 +168,7 @@ export default class CustomTabs extends Component {
|
||||
this.goToIndex(2);
|
||||
}
|
||||
if (this.page !== page) {
|
||||
this.props.onChangeTab({i: page, from: this.page});
|
||||
this.props.onChangeTab({ i: page, from: this.page });
|
||||
this.page = page;
|
||||
}
|
||||
};
|
||||
@@ -202,17 +196,14 @@ export default class CustomTabs extends Component {
|
||||
let drawerState = page === 0 && this.scrollOffset < 150;
|
||||
if (drawerState !== this.currentDrawerState) {
|
||||
this.currentDrawerState = drawerState;
|
||||
this.props.onDrawerStateChange &&
|
||||
this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
this.props.onDrawerStateChange && this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
}
|
||||
this.props.toggleOverlay(
|
||||
Math.floor(this.scrollOffset) < Math.floor(this.props.offsets.a - 10)
|
||||
? true
|
||||
: false
|
||||
Math.floor(this.scrollOffset) < Math.floor(this.props.offsets.a - 10) ? true : false
|
||||
);
|
||||
if (this.page !== page) {
|
||||
this.scrollEndTimeout = setTimeout(() => {
|
||||
this.props.onChangeTab({i: page, from: this.page});
|
||||
this.props.onChangeTab({ i: page, from: this.page });
|
||||
this.page = page;
|
||||
}, 50);
|
||||
}
|
||||
@@ -225,8 +216,7 @@ export default class CustomTabs extends Component {
|
||||
if (px > width * 0.75 || (DDS.isSmallTab && px > this.props.widths.a)) {
|
||||
this.goToIndex(1);
|
||||
this.currentDrawerState = false;
|
||||
this.props.onDrawerStateChange &&
|
||||
this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
this.props.onDrawerStateChange && this.props.onDrawerStateChange(this.currentDrawerState);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -239,10 +229,11 @@ export default class CustomTabs extends Component {
|
||||
onStartShouldSetResponderCapture={this.onMoveShouldSetResponder}
|
||||
style={{
|
||||
flex: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
ref={this.inputElement}
|
||||
style={{height: 1, padding: 0, width: 1, position: 'absolute'}}
|
||||
style={{ height: 1, padding: 0, width: 1, position: 'absolute' }}
|
||||
blurOnSubmit={false}
|
||||
/>
|
||||
<FlatList
|
||||
@@ -270,11 +261,7 @@ export default class CustomTabs extends Component {
|
||||
disableIntervalMomentum={true}
|
||||
decelerationRate="fast"
|
||||
snapToAlignment="start"
|
||||
snapToOffsets={[
|
||||
this.props.offsets.a,
|
||||
this.props.offsets.b,
|
||||
this.props.offsets.c
|
||||
]}
|
||||
snapToOffsets={[this.props.offsets.a, this.props.offsets.b, this.props.offsets.c]}
|
||||
contentOffset={{
|
||||
x: editing.movedAway ? this.props.offsets.a : this.props.offsets.b
|
||||
}}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import {
|
||||
Keyboard,
|
||||
KeyboardAvoidingView,
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
StyleSheet,
|
||||
TouchableOpacity
|
||||
} from 'react-native';
|
||||
import {useSettingStore} from '../../provider/stores';
|
||||
import { useSettingStore } from '../../provider/stores';
|
||||
import useIsFloatingKeyboard from '../../utils/use-is-floating-keyboard';
|
||||
import {BouncingView} from '../Transitions/bouncing-view';
|
||||
import { BouncingView } from '../Transitions/bouncing-view';
|
||||
|
||||
const BaseDialog = ({
|
||||
visible,
|
||||
@@ -60,18 +60,14 @@ const BaseDialog = ({
|
||||
if (!closeOnTouch) return null;
|
||||
useSettingStore.getState().setSheetKeyboardHandler(true);
|
||||
onRequestClose && onRequestClose();
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<SafeAreaView
|
||||
style={{
|
||||
backgroundColor: background
|
||||
? background
|
||||
: transparent
|
||||
? 'transparent'
|
||||
: 'rgba(0,0,0,0.3)'
|
||||
}}>
|
||||
<KeyboardAvoidingView
|
||||
enabled={!floating && Platform.OS === 'ios'}
|
||||
behavior="padding">
|
||||
backgroundColor: background ? background : transparent ? 'transparent' : 'rgba(0,0,0,0.3)'
|
||||
}}
|
||||
>
|
||||
<KeyboardAvoidingView enabled={!floating && Platform.OS === 'ios'} behavior="padding">
|
||||
<BouncingView
|
||||
duration={400}
|
||||
animated={animated}
|
||||
@@ -79,13 +75,10 @@ const BaseDialog = ({
|
||||
style={[
|
||||
styles.backdrop,
|
||||
{
|
||||
justifyContent: centered
|
||||
? 'center'
|
||||
: bottom
|
||||
? 'flex-end'
|
||||
: 'flex-start'
|
||||
justifyContent: centered ? 'center' : bottom ? 'flex-end' : 'flex-start'
|
||||
}
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<TouchableOpacity
|
||||
onPress={closeOnTouch ? onRequestClose : null}
|
||||
style={styles.overlayButton}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import {ActivityIndicator, StyleSheet, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
|
||||
const DialogButtons = ({
|
||||
onPressPositive,
|
||||
@@ -17,29 +17,31 @@ const DialogButtons = ({
|
||||
positiveType
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return (
|
||||
<View style={[styles.container,{
|
||||
backgroundColor:colors.nav,
|
||||
height:60,
|
||||
borderBottomRightRadius:10,
|
||||
borderBottomLeftRadius:10,
|
||||
paddingHorizontal:12
|
||||
}]}>
|
||||
<View
|
||||
style={[
|
||||
styles.container,
|
||||
{
|
||||
backgroundColor: colors.nav,
|
||||
height: 60,
|
||||
borderBottomRightRadius: 10,
|
||||
borderBottomLeftRadius: 10,
|
||||
paddingHorizontal: 12
|
||||
}
|
||||
]}
|
||||
>
|
||||
{loading ? (
|
||||
<ActivityIndicator color={colors.accent} size={SIZE.lg} />
|
||||
) : doneText ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
<Icon
|
||||
color={colors.accent}
|
||||
name="check-circle-outline"
|
||||
size={SIZE.md}
|
||||
/>
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.accent} name="check-circle-outline" size={SIZE.md} />
|
||||
<Paragraph color={colors.accent}>{' ' + doneText}</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
@@ -49,8 +51,9 @@ const DialogButtons = ({
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
}}>
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onPress={onPressNegative}
|
||||
fontSize={SIZE.md}
|
||||
@@ -65,10 +68,10 @@ const DialogButtons = ({
|
||||
fontSize={SIZE.md}
|
||||
testID={notesnook.ids.default.dialog.yes}
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
marginLeft: 10
|
||||
}}
|
||||
bold
|
||||
type={positiveType || "transparent"}
|
||||
type={positiveType || 'transparent'}
|
||||
title={positiveTitle}
|
||||
/>
|
||||
) : null}
|
||||
@@ -84,6 +87,6 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'row',
|
||||
marginTop: 10,
|
||||
},
|
||||
marginTop: 10
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,8 +4,8 @@ import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { getElevation } from '../../utils';
|
||||
|
||||
const DialogContainer = ({width, height, ...restProps}) => {
|
||||
const [state,] = useTracked();
|
||||
const DialogContainer = ({ width, height, ...restProps }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
return (
|
||||
@@ -17,7 +17,7 @@ const DialogContainer = ({width, height, ...restProps}) => {
|
||||
maxHeight: height || 450,
|
||||
borderRadius: 10,
|
||||
backgroundColor: colors.bg,
|
||||
paddingTop: 12,
|
||||
paddingTop: 12
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import {Text} from 'react-native';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { Text } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
@@ -29,22 +29,22 @@ const DialogHeader = ({
|
||||
justifyContent: 'space-between',
|
||||
minHeight: 50,
|
||||
paddingHorizontal: padding
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: centered ? 'center' : 'space-between',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.xl}>
|
||||
{title}{' '}
|
||||
{titlePart ? (
|
||||
<Text style={{color: colors.accent}}>{titlePart}</Text>
|
||||
) : null}
|
||||
{title} {titlePart ? <Text style={{ color: colors.accent }}>{titlePart}</Text> : null}
|
||||
</Heading>
|
||||
|
||||
{button ? (
|
||||
@@ -69,7 +69,8 @@ const DialogHeader = ({
|
||||
maxWidth: centered ? '90%' : '100%',
|
||||
alignSelf: centered ? 'center' : 'flex-start'
|
||||
}}
|
||||
color={paragraphColor || colors.icon}>
|
||||
color={paragraphColor || colors.icon}
|
||||
>
|
||||
{paragraph}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
@@ -1,28 +1,34 @@
|
||||
import { eSendEvent } from "../../services/EventManager";
|
||||
import { eCloseSimpleDialog, eOpenSimpleDialog } from "../../utils/Events";
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import { eCloseSimpleDialog, eOpenSimpleDialog } from '../../utils/Events';
|
||||
|
||||
type DialogInfo = {
|
||||
title?: string,
|
||||
paragraph?: string,
|
||||
positiveText?: string,
|
||||
negativeText?: string,
|
||||
positivePress?: (value:any) => void,
|
||||
onClose?: () => void,
|
||||
positiveType?: "transparent" | "gray" | "grayBg" | "accent" | "inverted" | "shade" | "error" | "errorShade",
|
||||
icon?: string,
|
||||
paragraphColor: string,
|
||||
input:boolean,
|
||||
inputPlaceholder:string,
|
||||
defaultValue:string,
|
||||
context:"global" | "local"
|
||||
}
|
||||
title?: string;
|
||||
paragraph?: string;
|
||||
positiveText?: string;
|
||||
negativeText?: string;
|
||||
positivePress?: (value: any) => void;
|
||||
onClose?: () => void;
|
||||
positiveType?:
|
||||
| 'transparent'
|
||||
| 'gray'
|
||||
| 'grayBg'
|
||||
| 'accent'
|
||||
| 'inverted'
|
||||
| 'shade'
|
||||
| 'error'
|
||||
| 'errorShade';
|
||||
icon?: string;
|
||||
paragraphColor: string;
|
||||
input: boolean;
|
||||
inputPlaceholder: string;
|
||||
defaultValue: string;
|
||||
context: 'global' | 'local';
|
||||
};
|
||||
|
||||
export function presentDialog(data: DialogInfo): void {
|
||||
eSendEvent(eOpenSimpleDialog, data);
|
||||
}
|
||||
|
||||
export function hideDialog(): void {
|
||||
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import BaseDialog from './base-dialog';
|
||||
import DialogButtons from './dialog-buttons';
|
||||
import DialogHeader from './dialog-header';
|
||||
|
||||
export const Dialog = ({context = 'global'}) => {
|
||||
export const Dialog = ({ context = 'global' }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
const [visible, setVisible] = useState(false);
|
||||
@@ -32,7 +32,7 @@ export const Dialog = ({context = 'global'}) => {
|
||||
input: false,
|
||||
inputPlaceholder: 'Enter some text',
|
||||
defaultValue: '',
|
||||
disableBackdropClosing:false
|
||||
disableBackdropClosing: false
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -48,9 +48,7 @@ export const Dialog = ({context = 'global'}) => {
|
||||
const onPressPositive = async () => {
|
||||
if (dialogInfo.positivePress) {
|
||||
inputRef.current?.blur();
|
||||
let result = await dialogInfo.positivePress(
|
||||
inputValue || dialogInfo.defaultValue
|
||||
);
|
||||
let result = await dialogInfo.positivePress(inputValue || dialogInfo.defaultValue);
|
||||
if (result === false) {
|
||||
return;
|
||||
}
|
||||
@@ -93,16 +91,16 @@ export const Dialog = ({context = 'global'}) => {
|
||||
closeOnTouch={!dialogInfo.disableBackdropClosing}
|
||||
onShow={async () => {
|
||||
if (dialogInfo.input) {
|
||||
|
||||
inputRef.current?.setNativeProps({
|
||||
text:dialogInfo.defaultValue
|
||||
text: dialogInfo.defaultValue
|
||||
});
|
||||
await sleep(300);
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
}}
|
||||
visible={true}
|
||||
onRequestClose={hide}>
|
||||
onRequestClose={hide}
|
||||
>
|
||||
<View style={style}>
|
||||
<DialogHeader
|
||||
title={dialogInfo.title}
|
||||
@@ -117,7 +115,8 @@ export const Dialog = ({context = 'global'}) => {
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
fwdRef={inputRef}
|
||||
autoCapitalize="none"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import {
|
||||
eCloseActionSheet,
|
||||
eCloseAddNotebookDialog,
|
||||
|
||||
@@ -33,10 +33,7 @@ export class DialogManager extends Component {
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
return (
|
||||
JSON.stringify(nextProps) !== JSON.stringify(this.props) ||
|
||||
nextState !== this.state
|
||||
);
|
||||
return JSON.stringify(nextProps) !== JSON.stringify(this.props) || nextState !== this.state;
|
||||
}
|
||||
|
||||
onThemeChange = () => {
|
||||
@@ -54,7 +51,7 @@ export class DialogManager extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
let {colors} = this.state;
|
||||
let { colors } = this.state;
|
||||
return (
|
||||
<>
|
||||
<Dialog context="global" />
|
||||
|
||||
@@ -18,18 +18,12 @@ import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} = require('../../services/EventManager');
|
||||
const {
|
||||
eOpenExportDialog,
|
||||
eCloseExportDialog,
|
||||
} = require('../../utils/Events');
|
||||
const { eSubscribeEvent, eUnSubscribeEvent } = require('../../services/EventManager');
|
||||
const { eOpenExportDialog, eCloseExportDialog } = require('../../utils/Events');
|
||||
|
||||
const ExportDialog = () => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const [visible, setVisible] = useState(false);
|
||||
const actionSheetRef = useRef();
|
||||
@@ -75,9 +69,7 @@ const ExportDialog = () => {
|
||||
}
|
||||
setDoneText(
|
||||
`Note exported successfully! You can find the exported note in ${
|
||||
Platform.OS === 'ios'
|
||||
? 'Files Manager/Notesnook'
|
||||
: `Storage/Notesnook/exported/${name}`
|
||||
Platform.OS === 'ios' ? 'Files Manager/Notesnook' : `Storage/Notesnook/exported/${name}`
|
||||
}.`
|
||||
);
|
||||
|
||||
@@ -137,13 +129,12 @@ const ExportDialog = () => {
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
icon="export"
|
||||
title="Export Note"
|
||||
paragraph={
|
||||
'All exports are saved in Notesnook/exported folder in phone storage'
|
||||
}
|
||||
paragraph={'All exports are saved in Notesnook/exported folder in phone storage'}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -163,7 +154,8 @@ const ExportDialog = () => {
|
||||
justifyContent: 'flex-start',
|
||||
borderRadius: 0,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: colors.shade,
|
||||
@@ -172,24 +164,19 @@ const ExportDialog = () => {
|
||||
width: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Icon
|
||||
name={item.icon}
|
||||
color={colors.accent}
|
||||
size={SIZE.xxxl + 10}
|
||||
/>
|
||||
}}
|
||||
>
|
||||
<Icon name={item.icon} color={colors.accent} size={SIZE.xxxl + 10} />
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
flexShrink: 1
|
||||
}}>
|
||||
<Heading style={{marginLeft: 10}} size={SIZE.md}>
|
||||
}}
|
||||
>
|
||||
<Heading style={{ marginLeft: 10 }} size={SIZE.md}>
|
||||
{item.title}
|
||||
</Heading>
|
||||
<Paragraph
|
||||
style={{marginLeft: 10}}
|
||||
size={SIZE.sm}
|
||||
color={colors.icon}>
|
||||
<Paragraph style={{ marginLeft: 10 }} size={SIZE.sm} color={colors.icon}>
|
||||
{item.desc}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -202,7 +189,8 @@ const ExportDialog = () => {
|
||||
width: '100%',
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{complete && (
|
||||
<>
|
||||
<Button
|
||||
@@ -259,13 +247,12 @@ const ExportDialog = () => {
|
||||
marginTop: 5
|
||||
}}
|
||||
color={colors.icon}
|
||||
size={SIZE.xs}>
|
||||
size={SIZE.xs}
|
||||
>
|
||||
{'Note exported as ' + result.fileName}
|
||||
</Paragraph>
|
||||
)}
|
||||
{exporting && !complete && (
|
||||
<Button loading={true} height={50} width="100%" />
|
||||
)}
|
||||
{exporting && !complete && <Button loading={true} height={50} width="100%" />}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import FileViewer from 'react-native-file-viewer';
|
||||
import Share from 'react-native-share';
|
||||
import {ToastEvent} from '../../services/EventManager';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { ToastEvent } from '../../services/EventManager';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const ShareComponent = ({uri, name, padding}) => {
|
||||
export const ShareComponent = ({ uri, name, padding }) => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: padding
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title="Open"
|
||||
type="accent"
|
||||
|
||||
@@ -15,9 +15,9 @@ import SheetWrapper from '../Sheet';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const GeneralSheet = ({context}) => {
|
||||
const GeneralSheet = ({ context }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [dialogData, setDialogData] = useState(null);
|
||||
const actionSheetRef = useRef();
|
||||
@@ -35,10 +35,7 @@ const GeneralSheet = ({context}) => {
|
||||
}, [visible]);
|
||||
|
||||
const open = async data => {
|
||||
if (
|
||||
(data.context && !context) ||
|
||||
(data.context && data.context !== context)
|
||||
) {
|
||||
if ((data.context && !context) || (data.context && data.context !== context)) {
|
||||
return;
|
||||
}
|
||||
if (visible || dialogData) {
|
||||
@@ -92,20 +89,19 @@ const GeneralSheet = ({context}) => {
|
||||
dialogData.onClose && dialogData.onClose();
|
||||
setVisible(false);
|
||||
setDialogData(null);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom:
|
||||
!dialogData.progress &&
|
||||
!dialogData.icon &&
|
||||
!dialogData.title &&
|
||||
!dialogData.paragraph
|
||||
!dialogData.progress && !dialogData.icon && !dialogData.title && !dialogData.paragraph
|
||||
? 0
|
||||
: 10,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{dialogData?.progress ? (
|
||||
<ActivityIndicator
|
||||
style={{
|
||||
@@ -127,9 +123,7 @@ const GeneralSheet = ({context}) => {
|
||||
{dialogData?.title ? <Heading> {dialogData?.title}</Heading> : null}
|
||||
|
||||
{dialogData?.paragraph ? (
|
||||
<Paragraph style={{textAlign: 'center'}}>
|
||||
{dialogData?.paragraph}
|
||||
</Paragraph>
|
||||
<Paragraph style={{ textAlign: 'center' }}>{dialogData?.paragraph}</Paragraph>
|
||||
) : null}
|
||||
</View>
|
||||
|
||||
@@ -141,14 +135,15 @@ const GeneralSheet = ({context}) => {
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: dialogData.valueArray ? 12 : 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{dialogData.valueArray &&
|
||||
dialogData.valueArray.map(v => (
|
||||
<Button
|
||||
title={v}
|
||||
type="gray"
|
||||
key={v}
|
||||
textStyle={{fontWeight: 'normal'}}
|
||||
textStyle={{ fontWeight: 'normal' }}
|
||||
fontSize={SIZE.sm}
|
||||
icon="check"
|
||||
width="100%"
|
||||
@@ -163,7 +158,8 @@ const GeneralSheet = ({context}) => {
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{dialogData?.action ? (
|
||||
<Button
|
||||
onPress={dialogData.action}
|
||||
@@ -171,7 +167,6 @@ const GeneralSheet = ({context}) => {
|
||||
title={dialogData.actionText}
|
||||
accentColor={dialogData.iconColor || 'accent'}
|
||||
accentText="light"
|
||||
fontSize={SIZE.lg}
|
||||
type="accent"
|
||||
height={50}
|
||||
width="100%"
|
||||
@@ -205,12 +200,9 @@ const GeneralSheet = ({context}) => {
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
onPress={dialogData.learnMorePress}
|
||||
color={colors.icon}>
|
||||
<Icon
|
||||
color={colors.icon}
|
||||
name="information-outline"
|
||||
size={SIZE.xs}
|
||||
/>{' '}
|
||||
color={colors.icon}
|
||||
>
|
||||
<Icon color={colors.icon} name="information-outline" size={SIZE.xs} />{' '}
|
||||
{dialogData.learnMore}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useTracked } from '../../provider';
|
||||
import { useUserStore } from '../../provider/stores';
|
||||
import { eSendEvent, ToastEvent } from '../../services/EventManager';
|
||||
import PremiumService from '../../services/PremiumService';
|
||||
import { APP_VERSION } from "../../../version";
|
||||
import { APP_VERSION } from '../../../version';
|
||||
import { db } from '../../utils/database';
|
||||
import { eCloseProgressDialog } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
@@ -29,9 +29,8 @@ export const Issue = () => {
|
||||
const onPress = async () => {
|
||||
if (loading) return;
|
||||
if (!title.current || !body.current) return;
|
||||
if (title.current?.trim() === '' || body.current?.trim().length === 0)
|
||||
return;
|
||||
|
||||
if (title.current?.trim() === '' || body.current?.trim().length === 0) return;
|
||||
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
@@ -43,8 +42,8 @@ export const Issue = () => {
|
||||
**Device information:**
|
||||
App version: ${APP_VERSION}
|
||||
Platform: ${Platform.OS}
|
||||
Model: ${Platform.constants.Brand || ""}-${Platform.constants.Model|| ""}-${
|
||||
Platform.constants.Version || ""
|
||||
Model: ${Platform.constants.Brand || ''}-${Platform.constants.Model || ''}-${
|
||||
Platform.constants.Version || ''
|
||||
}
|
||||
Pro: ${PremiumService.get()}
|
||||
Logged in: ${user ? 'yes' : 'no'}`,
|
||||
@@ -65,11 +64,12 @@ Logged in: ${user ? 'yes' : 'no'}`,
|
||||
}}
|
||||
onPress={() => {
|
||||
Linking.openURL(issue_url);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{issue_url}.
|
||||
</Text>{' '}
|
||||
Please note that we will respond to your issue on the given link. We
|
||||
recommend that you save it.
|
||||
Please note that we will respond to your issue on the given link. We recommend that you
|
||||
save it.
|
||||
</Text>
|
||||
),
|
||||
positiveText: 'Copy link',
|
||||
@@ -97,7 +97,8 @@ Logged in: ${user ? 'yes' : 'no'}`,
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Report issue"
|
||||
paragraph="Let us know if you have faced any issue/bug while using Notesnook."
|
||||
@@ -116,7 +117,7 @@ Logged in: ${user ? 'yes' : 'no'}`,
|
||||
fontFamily: 'OpenSans-Regular',
|
||||
marginBottom: 10,
|
||||
fontSize: SIZE.md,
|
||||
color:colors.heading,
|
||||
color: colors.heading
|
||||
}}
|
||||
placeholderTextColor={colors.placeholder}
|
||||
/>
|
||||
@@ -140,15 +141,14 @@ For example:
|
||||
maxHeight: 200,
|
||||
fontSize: SIZE.sm,
|
||||
marginBottom: 2.5,
|
||||
color:colors.pri
|
||||
color: colors.pri
|
||||
}}
|
||||
placeholderTextColor={colors.placeholder}
|
||||
/>
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
color={
|
||||
colors.icon
|
||||
}>{`App version: ${APP_VERSION} Platform: ${Platform.OS} Model: ${Platform.constants.Brand}-${Platform.constants.Model}-${Platform.constants.Version}`}</Paragraph>
|
||||
color={colors.icon}
|
||||
>{`App version: ${APP_VERSION} Platform: ${Platform.OS} Model: ${Platform.constants.Brand}-${Platform.constants.Model}-${Platform.constants.Version}`}</Paragraph>
|
||||
|
||||
<Seperator />
|
||||
<Button
|
||||
@@ -166,7 +166,8 @@ For example:
|
||||
style={{
|
||||
marginTop: 10,
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
The information above will be publically available at{' '}
|
||||
<Text
|
||||
onPress={() => {
|
||||
@@ -175,11 +176,11 @@ For example:
|
||||
style={{
|
||||
textDecorationLine: 'underline',
|
||||
color: colors.accent
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
github.com/streetwriters/notesnook.
|
||||
</Text>{' '}
|
||||
If you want to ask something in general or need some assistance, we
|
||||
would suggest that you{' '}
|
||||
If you want to ask something in general or need some assistance, we would suggest that you{' '}
|
||||
<Text
|
||||
style={{
|
||||
textDecorationLine: 'underline',
|
||||
@@ -189,7 +190,8 @@ For example:
|
||||
try {
|
||||
await openLinkInBrowser('https://discord.gg/zQBK97EE22', colors);
|
||||
} catch (e) {}
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
join our community on Discord.
|
||||
</Text>
|
||||
</Paragraph>
|
||||
|
||||
@@ -7,9 +7,9 @@ import Navigation from '../../services/Navigation';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
|
||||
export const HeaderLeftMenu = ({currentScreen,headerMenuState}) => {
|
||||
export const HeaderLeftMenu = ({ currentScreen, headerMenuState }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const deviceMode = useSettingStore(state => state.deviceMode);
|
||||
|
||||
const onLeftButtonPress = () => {
|
||||
@@ -20,12 +20,9 @@ export const HeaderLeftMenu = ({currentScreen,headerMenuState}) => {
|
||||
Navigation.goBack();
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{deviceMode !== "tablet" ||
|
||||
currentScreen === 'Search' ||
|
||||
!headerMenuState ? (
|
||||
{deviceMode !== 'tablet' || currentScreen === 'Search' || !headerMenuState ? (
|
||||
<ActionIcon
|
||||
testID={notesnook.ids.default.header.buttons.left}
|
||||
customStyle={{
|
||||
@@ -35,11 +32,11 @@ export const HeaderLeftMenu = ({currentScreen,headerMenuState}) => {
|
||||
width: 40,
|
||||
borderRadius: 100,
|
||||
marginLeft: -5,
|
||||
marginRight:DDS.isLargeTablet()? 10 : 25,
|
||||
marginRight: DDS.isLargeTablet() ? 10 : 25
|
||||
}}
|
||||
left={40}
|
||||
top={40}
|
||||
right={DDS.isLargeTablet()? 10 : 25}
|
||||
right={DDS.isLargeTablet() ? 10 : 25}
|
||||
onPress={onLeftButtonPress}
|
||||
onLongPress={() => {
|
||||
Navigation.popToTop();
|
||||
@@ -47,7 +44,7 @@ export const HeaderLeftMenu = ({currentScreen,headerMenuState}) => {
|
||||
name={!headerMenuState ? 'arrow-left' : 'menu'}
|
||||
color={colors.pri}
|
||||
iconStyle={{
|
||||
marginLeft: !headerMenuState ? -5 : 0,
|
||||
marginLeft: !headerMenuState ? -5 : 0
|
||||
}}
|
||||
/>
|
||||
) : undefined}
|
||||
|
||||
@@ -11,9 +11,9 @@ import { sleep } from '../../utils/TimeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
export const HeaderRightMenu = ({ currentScreen, action, rightButtons }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const deviceMode = useSettingStore(state => state.deviceMode);
|
||||
const menuRef = useRef();
|
||||
return (
|
||||
@@ -25,7 +25,6 @@ export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
menu: false
|
||||
});
|
||||
}}
|
||||
|
||||
name="magnify"
|
||||
color={colors.pri}
|
||||
customStyle={styles.rightBtn}
|
||||
@@ -40,10 +39,10 @@ export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
iconSize={SIZE.xl}
|
||||
type="shade"
|
||||
hitSlop={{
|
||||
top:10,
|
||||
right:10,
|
||||
bottom:10,
|
||||
left:0
|
||||
top: 10,
|
||||
right: 10,
|
||||
bottom: 10,
|
||||
left: 0
|
||||
}}
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
@@ -51,8 +50,8 @@ export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
height: 32,
|
||||
borderRadius: 5,
|
||||
paddingHorizontal: 0,
|
||||
borderWidth:1,
|
||||
borderColor:colors.accent
|
||||
borderWidth: 1,
|
||||
borderColor: colors.accent
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
@@ -75,7 +74,8 @@ export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
color={colors.pri}
|
||||
customStyle={styles.rightBtn}
|
||||
/>
|
||||
}>
|
||||
}
|
||||
>
|
||||
{rightButtons.map((item, index) => (
|
||||
<MenuItem
|
||||
key={item.title}
|
||||
@@ -87,7 +87,8 @@ export const HeaderRightMenu = ({currentScreen, action, rightButtons}) => {
|
||||
textStyle={{
|
||||
fontSize: SIZE.md,
|
||||
color: colors.pri
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name={item.icon} size={SIZE.md} />
|
||||
{' ' + item.title}
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
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 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 SearchService from '../../services/SearchService';
|
||||
import {eScrollEvent} from '../../utils/Events';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {SearchInput} from '../SearchInput';
|
||||
import {HeaderLeftMenu} from './HeaderLeftMenu';
|
||||
import {HeaderRightMenu} from './HeaderRightMenu';
|
||||
import {Title} from './title';
|
||||
import { eScrollEvent } from '../../utils/Events';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { SearchInput } from '../SearchInput';
|
||||
import { HeaderLeftMenu } from './HeaderLeftMenu';
|
||||
import { HeaderRightMenu } from './HeaderRightMenu';
|
||||
import { Title } from './title';
|
||||
|
||||
export const Header = React.memo(
|
||||
({root, title, screen, isBack, color, action, rightButtons, notebook}) => {
|
||||
({ root, title, screen, isBack, color, action, rightButtons, notebook }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const insets = useSafeAreaInsets();
|
||||
const [hide, setHide] = useState(true);
|
||||
|
||||
@@ -44,9 +44,10 @@ export const Header = React.memo(
|
||||
overflow: 'hidden',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: hide ? 'transparent' : colors.nav,
|
||||
justifyContent: 'space-between',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<View style={styles.leftBtnContainer}>
|
||||
<HeaderLeftMenu headerMenuState={!isBack} currentScreen={screen} />
|
||||
|
||||
@@ -59,11 +60,7 @@ export const Header = React.memo(
|
||||
/>
|
||||
</View>
|
||||
|
||||
<HeaderRightMenu
|
||||
rightButtons={rightButtons}
|
||||
action={action}
|
||||
currentScreen={screen}
|
||||
/>
|
||||
<HeaderRightMenu rightButtons={rightButtons} action={action} currentScreen={screen} />
|
||||
</View>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {eOnNewTopicAdded, eScrollEvent} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { eOnNewTopicAdded, eScrollEvent } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Title = ({heading, headerColor, screen, notebook}) => {
|
||||
export const Title = ({ heading, headerColor, screen, notebook }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [hide, setHide] = useState(screen === 'Notebook' ? true : false);
|
||||
|
||||
const onScroll = data => {
|
||||
@@ -59,7 +55,8 @@ export const Title = ({heading, headerColor, screen, notebook}) => {
|
||||
opacity: 1,
|
||||
flexShrink: 1,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{!hide ? (
|
||||
<Heading
|
||||
onPress={navigateToNotebook}
|
||||
@@ -68,16 +65,15 @@ export const Title = ({heading, headerColor, screen, notebook}) => {
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
color={headerColor}>
|
||||
color={headerColor}
|
||||
>
|
||||
{notebook ? (
|
||||
<Paragraph numberOfLines={1} size={SIZE.xs + 1}>
|
||||
{notebook?.title}
|
||||
{'\n'}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
<Heading color={colors.accent}>
|
||||
{heading.slice(0, 1) === '#' ? '#' : null}
|
||||
</Heading>
|
||||
<Heading color={colors.accent}>{heading.slice(0, 1) === '#' ? '#' : null}</Heading>
|
||||
{heading.slice(0, 1) === '#' ? heading.slice(1) : heading}
|
||||
</Heading>
|
||||
) : null}
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||
import RNFetchBlob from 'rn-fetch-blob';
|
||||
import Storage from '../../utils/storage';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
const {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} = require('../../services/EventManager');
|
||||
const { eSubscribeEvent, eUnSubscribeEvent } = require('../../services/EventManager');
|
||||
|
||||
const ImagePreview = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
@@ -40,7 +37,8 @@ const ImagePreview = () => {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
backgroundColor: 'black'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ImageViewer
|
||||
enableImageZoom={true}
|
||||
renderIndicator={() => <></>}
|
||||
@@ -62,7 +60,8 @@ const ImagePreview = () => {
|
||||
zIndex: 999,
|
||||
backgroundColor: 'rgba(0,0,0,0.3)',
|
||||
paddingTop: 30
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
name="close"
|
||||
color="white"
|
||||
@@ -78,8 +77,6 @@ const ImagePreview = () => {
|
||||
}
|
||||
]}
|
||||
/>
|
||||
|
||||
|
||||
</View>
|
||||
</BaseDialog>
|
||||
)
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React, {useState} from 'react';
|
||||
import {TouchableOpacity,TextInput} from 'react-native';
|
||||
import {View} from 'react-native';
|
||||
import React, { useState } from 'react';
|
||||
import { TouchableOpacity, TextInput } from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider/index';
|
||||
import { useTracked } from '../../provider/index';
|
||||
import {
|
||||
ERRORS_LIST,
|
||||
validateEmail,
|
||||
validatePass,
|
||||
validateUsername
|
||||
} from '../../services/Validation';
|
||||
import {getElevation} from '../../utils';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import { getElevation } from '../../utils';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const Input = ({
|
||||
@@ -43,7 +43,7 @@ const Input = ({
|
||||
onFocusInput,
|
||||
buttons,
|
||||
marginRight,
|
||||
autoCorrect=true,
|
||||
autoCorrect = true,
|
||||
buttonLeft
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
@@ -60,11 +60,7 @@ const Input = ({
|
||||
// SPECIAL: true,
|
||||
});
|
||||
|
||||
const color = error
|
||||
? colors.red
|
||||
: focus
|
||||
? customColor || colors.accent
|
||||
: colors.nav;
|
||||
const color = error ? colors.red : focus ? customColor || colors.accent : colors.nav;
|
||||
|
||||
const validate = value => {
|
||||
if (!validationType) return;
|
||||
@@ -142,7 +138,7 @@ const Input = ({
|
||||
flexGrow: 1,
|
||||
height: height || 50,
|
||||
paddingHorizontal: 12,
|
||||
paddingRight:buttons || button || secureTextEntry || error ? 6 : 12
|
||||
paddingRight: buttons || button || secureTextEntry || error ? 6 : 12
|
||||
};
|
||||
|
||||
const textStyle = {
|
||||
@@ -153,7 +149,7 @@ const Input = ({
|
||||
paddingBottom: 2.5,
|
||||
flexGrow: 1,
|
||||
height: height || 50,
|
||||
fontFamily:"OpenSans-Regular"
|
||||
fontFamily: 'OpenSans-Regular'
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -165,16 +161,11 @@ const Input = ({
|
||||
marginBottom: marginBottom,
|
||||
flexGrow: 1,
|
||||
maxHeight: height,
|
||||
marginRight:marginRight
|
||||
}}>
|
||||
<TouchableOpacity
|
||||
disabled={!loading}
|
||||
onPress={onPress}
|
||||
activeOpacity={1}
|
||||
style={style}>
|
||||
{
|
||||
buttonLeft && buttonLeft
|
||||
}
|
||||
marginRight: marginRight
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity disabled={!loading} onPress={onPress} activeOpacity={1} style={style}>
|
||||
{buttonLeft && buttonLeft}
|
||||
|
||||
<TextInput
|
||||
ref={fwdRef}
|
||||
@@ -185,9 +176,7 @@ const Input = ({
|
||||
onChangeText={onChange}
|
||||
autoCorrect={autoCorrect}
|
||||
onBlur={onBlur}
|
||||
keyboardType={
|
||||
validationType === 'email' ? 'email-address' : 'default'
|
||||
}
|
||||
keyboardType={validationType === 'email' ? 'email-address' : 'default'}
|
||||
importantForAutofill="yes"
|
||||
importantForAccessibility="yes"
|
||||
returnKeyLabel={returnKeyLabel}
|
||||
@@ -209,7 +198,8 @@ const Input = ({
|
||||
justifyContent: 'center',
|
||||
height: 35 > height ? height : 35,
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{secureTextEntry && (
|
||||
<ActionIcon
|
||||
name="eye"
|
||||
@@ -269,18 +259,16 @@ const Input = ({
|
||||
borderRadius: 2.5,
|
||||
...getElevation(2),
|
||||
top: 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
textAlign: 'right',
|
||||
textAlignVertical: 'bottom'
|
||||
}}>
|
||||
<Icon
|
||||
name="alert-circle-outline"
|
||||
size={SIZE.xs}
|
||||
color={colors.errorText}
|
||||
/>{' '}
|
||||
}}
|
||||
>
|
||||
<Icon name="alert-circle-outline" size={SIZE.xs} color={colors.errorText} />{' '}
|
||||
{errorMessage}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -292,22 +280,23 @@ const Input = ({
|
||||
<View
|
||||
style={{
|
||||
paddingTop: 5
|
||||
}}>
|
||||
{Object.keys(errorList).filter(k => errorList[k] === true).length !==
|
||||
0 ? (
|
||||
}}
|
||||
>
|
||||
{Object.keys(errorList).filter(k => errorList[k] === true).length !== 0 ? (
|
||||
Object.keys(ERRORS_LIST).map(error => (
|
||||
<View
|
||||
key={ERRORS_LIST[error]}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name={errorList[error] ? 'close' : 'check'}
|
||||
color={errorList[error] ? 'red' : 'green'}
|
||||
/>
|
||||
|
||||
<Paragraph style={{marginLeft: 5}} size={SIZE.xs}>
|
||||
<Paragraph style={{ marginLeft: 5 }} size={SIZE.xs}>
|
||||
{ERRORS_LIST[error]}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -1,35 +1,29 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import BaseDialog from '../../components/Dialog/base-dialog';
|
||||
import {PressableButton} from '../../components/PressableButton';
|
||||
import { PressableButton } from '../../components/PressableButton';
|
||||
import Seperator from '../../components/Seperator';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMessageStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import {getElevation} from '../../utils';
|
||||
import {
|
||||
eCloseJumpToDialog,
|
||||
eOpenJumpToDialog,
|
||||
eScrollEvent
|
||||
} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMessageStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { getElevation } from '../../utils';
|
||||
import { eCloseJumpToDialog, eOpenJumpToDialog, eScrollEvent } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const offsets = [];
|
||||
let timeout = null;
|
||||
const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
const JumpToDialog = ({ scrollRef, data, type, screen }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const notes = data;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [currentIndex, setCurrentIndex] = useState(null);
|
||||
|
||||
const onPress = (item, index) => {
|
||||
let ind = notes.findIndex(
|
||||
i => i.title === item.title && i.type === 'header'
|
||||
);
|
||||
let ind = notes.findIndex(i => i.title === item.title && i.type === 'header');
|
||||
console.log(ind);
|
||||
scrollRef.current?.scrollToIndex({
|
||||
index: ind,
|
||||
@@ -80,9 +74,7 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
.filter(i => i.type === 'header')
|
||||
.map((item, index) => {
|
||||
let offset = 35 * index;
|
||||
let ind = notes.findIndex(
|
||||
i => i.title === item.title && i.type === 'header'
|
||||
);
|
||||
let ind = notes.findIndex(i => i.title === item.title && i.type === 'header');
|
||||
let messageState = useMessageStore.getState().message;
|
||||
let msgOffset = messageState?.visible ? 60 : 10;
|
||||
ind = ind + 1;
|
||||
@@ -98,7 +90,8 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
loadOffsets();
|
||||
}}
|
||||
onRequestClose={close}
|
||||
visible={true}>
|
||||
visible={true}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
...getElevation(5),
|
||||
@@ -111,11 +104,13 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
alignSelf: 'center',
|
||||
padding: 10,
|
||||
paddingTop: 30
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ScrollView
|
||||
style={{
|
||||
maxHeight: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
@@ -123,7 +118,8 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
alignSelf: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingBottom: 20
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{notes
|
||||
.filter(i => i.type === 'header')
|
||||
.map((item, index) => {
|
||||
@@ -140,15 +136,15 @@ const JumpToDialog = ({scrollRef, data, type, screen}) => {
|
||||
borderRadius: 100,
|
||||
height: 25,
|
||||
marginVertical: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={SIZE.sm}
|
||||
color={
|
||||
currentIndex === index ? colors.light : colors.accent
|
||||
}
|
||||
color={currentIndex === index ? colors.light : colors.accent}
|
||||
style={{
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</PressableButton>
|
||||
|
||||
@@ -14,54 +14,55 @@ import {
|
||||
TRASH_SVG
|
||||
} from '../../assets/images/assets';
|
||||
import { useTracked } from '../../provider';
|
||||
export const Placeholder = ({type, w, h, color}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const getSVG = () => {
|
||||
switch (type) {
|
||||
case 'notes':
|
||||
return NOTE_SVG(color || colors.accent);
|
||||
case 'notebooks':
|
||||
return NOTEBOOK_SVG(colors.accent);
|
||||
case 'topics':
|
||||
return TOPIC_SVG(colors.accent);
|
||||
case 'tags':
|
||||
return TAG_SVG(colors.accent);
|
||||
case 'favorites':
|
||||
return FAV_SVG(colors.accent);
|
||||
case 'trash':
|
||||
return TRASH_SVG(colors.accent);
|
||||
case 'settings':
|
||||
return SETTINGS_SVG(colors.accent);
|
||||
case 'search':
|
||||
return SEARCH_SVG(colors.accent);
|
||||
case 'login':
|
||||
return LOGIN_SVG(colors.accent);
|
||||
case 'signup':
|
||||
return LOGO_SVG;
|
||||
}
|
||||
};
|
||||
export const Placeholder = ({ type, w, h, color }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const { colors } = state;
|
||||
const getSVG = () => {
|
||||
switch (type) {
|
||||
case 'notes':
|
||||
return NOTE_SVG(color || colors.accent);
|
||||
case 'notebooks':
|
||||
return NOTEBOOK_SVG(colors.accent);
|
||||
case 'topics':
|
||||
return TOPIC_SVG(colors.accent);
|
||||
case 'tags':
|
||||
return TAG_SVG(colors.accent);
|
||||
case 'favorites':
|
||||
return FAV_SVG(colors.accent);
|
||||
case 'trash':
|
||||
return TRASH_SVG(colors.accent);
|
||||
case 'settings':
|
||||
return SETTINGS_SVG(colors.accent);
|
||||
case 'search':
|
||||
return SEARCH_SVG(colors.accent);
|
||||
case 'login':
|
||||
return LOGIN_SVG(colors.accent);
|
||||
case 'signup':
|
||||
return LOGO_SVG;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SvgToPngView
|
||||
color={type === 'notes' ? color || colors.accent : colors.accent}
|
||||
src={getSVG()}
|
||||
img={type}
|
||||
width={w}
|
||||
height={h}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<SvgToPngView
|
||||
color={type === 'notes' ? color || colors.accent : colors.accent}
|
||||
src={getSVG()}
|
||||
img={type}
|
||||
width={w}
|
||||
height={h}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const SvgToPngView = ({width, height, src, color, img}) => {
|
||||
export const SvgToPngView = ({ width, height, src, color, img }) => {
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
height: width || 250,
|
||||
width: height || 250,
|
||||
}}>
|
||||
width: height || 250
|
||||
}}
|
||||
>
|
||||
<SvgXml xml={src} width="100%" height="100%" />
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import {ActivityIndicator, StyleSheet, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {ph, pv, SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { ActivityIndicator, StyleSheet, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { ph, pv, SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Loading = ({
|
||||
@@ -11,24 +11,22 @@ export const Loading = ({
|
||||
done = false,
|
||||
doneText = 'Action completed successfully!',
|
||||
onDone = () => {},
|
||||
customStyle = {},
|
||||
customStyle = {}
|
||||
}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{height: height, backgroundColor: colors.bg},
|
||||
{ height: height, backgroundColor: colors.bg },
|
||||
styles.activityContainer,
|
||||
customStyle,
|
||||
]}>
|
||||
customStyle
|
||||
]}
|
||||
>
|
||||
{done ? (
|
||||
<>
|
||||
<Paragraph
|
||||
color={colors.icon}
|
||||
size={SIZE.xs}
|
||||
style={styles.activityText}>
|
||||
<Paragraph color={colors.icon} size={SIZE.xs} style={styles.activityText}>
|
||||
{doneText}
|
||||
</Paragraph>
|
||||
|
||||
@@ -40,9 +38,10 @@ export const Loading = ({
|
||||
<Paragraph
|
||||
size={SIZE.md}
|
||||
style={{
|
||||
marginTop:10
|
||||
marginTop: 10
|
||||
}}
|
||||
color={colors.pri}>
|
||||
color={colors.pri}
|
||||
>
|
||||
{tagline}
|
||||
</Paragraph>
|
||||
</>
|
||||
@@ -55,11 +54,11 @@ const styles = StyleSheet.create({
|
||||
activityText: {
|
||||
fontSize: SIZE.sm,
|
||||
textAlign: 'center',
|
||||
marginBottom: 10,
|
||||
marginBottom: 10
|
||||
},
|
||||
activityContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
button: {
|
||||
paddingVertical: pv,
|
||||
@@ -71,11 +70,11 @@ const styles = StyleSheet.create({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
borderWidth: 1,
|
||||
flexDirection: 'row',
|
||||
flexDirection: 'row'
|
||||
},
|
||||
buttonText: {
|
||||
//fontFamily: "sans-serif",
|
||||
color: 'white',
|
||||
fontSize: SIZE.sm,
|
||||
},
|
||||
fontSize: SIZE.sm
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {ScrollView, Text, TouchableOpacity, View} from 'react-native';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {Button} from '../../components/Button';
|
||||
import { Button } from '../../components/Button';
|
||||
import Seperator from '../../components/Seperator';
|
||||
import {useTracked} from '../../provider/index';
|
||||
import {useUserStore} from '../../provider/stores';
|
||||
import { useTracked } from '../../provider/index';
|
||||
import { useUserStore } from '../../provider/stores';
|
||||
import BiometricService from '../../services/BiometricService';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
@@ -14,26 +14,26 @@ import {
|
||||
presentSheet,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import {clearMessage, setEmailVerifyMessage} from '../../services/Message';
|
||||
import { clearMessage, setEmailVerifyMessage } from '../../services/Message';
|
||||
import PremiumService from '../../services/PremiumService';
|
||||
import Sync from '../../services/Sync';
|
||||
import {hexToRGBA} from '../../utils/ColorUtils';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOpenLoginDialog, eOpenResultDialog} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { hexToRGBA } from '../../utils/ColorUtils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenLoginDialog, eOpenResultDialog } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Storage from '../../utils/storage';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import DialogButtons from '../Dialog/dialog-buttons';
|
||||
import DialogContainer from '../Dialog/dialog-container';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Input from '../Input';
|
||||
import {Header} from '../SimpleList/header';
|
||||
import { Header } from '../SimpleList/header';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import umami from '../../utils/umami';
|
||||
|
||||
const MODES = {
|
||||
@@ -145,8 +145,7 @@ const LoginDialog = () => {
|
||||
buttonFunc: () => changePassword(),
|
||||
headerParagraph: 'login to your account',
|
||||
showForgotButton: false,
|
||||
loading:
|
||||
'Please wait while we change your password and encrypt your data.',
|
||||
loading: 'Please wait while we change your password and encrypt your data.',
|
||||
showLoader: true,
|
||||
buttonAlt: null
|
||||
},
|
||||
@@ -182,8 +181,7 @@ const LoginDialog = () => {
|
||||
console.log('REQUESTING NEW TOKEN');
|
||||
let res = await db.user.tokenManager.getToken();
|
||||
if (!res) throw new Error('no token found');
|
||||
if (db.user.tokenManager._isTokenExpired(res))
|
||||
throw new Error('token expired');
|
||||
if (db.user.tokenManager._isTokenExpired(res)) throw new Error('token expired');
|
||||
if (!(await Sync.run())) throw new Error('e');
|
||||
await MMKV.removeItem('loginSessionHasExpired');
|
||||
return;
|
||||
@@ -279,8 +277,7 @@ const LoginDialog = () => {
|
||||
if (error) {
|
||||
ToastEvent.show({
|
||||
heading: 'Invalid signup information',
|
||||
message:
|
||||
'Some or all information provided is invalid. Resolve all errors and try again.',
|
||||
message: 'Some or all information provided is invalid. Resolve all errors and try again.',
|
||||
type: 'error',
|
||||
context: 'local'
|
||||
});
|
||||
@@ -346,10 +343,7 @@ const LoginDialog = () => {
|
||||
}
|
||||
try {
|
||||
let lastRecoveryEmailTime = await MMKV.getItem('lastRecoveryEmailTime');
|
||||
if (
|
||||
lastRecoveryEmailTime &&
|
||||
Date.now() - JSON.parse(lastRecoveryEmailTime) < 60000 * 3
|
||||
) {
|
||||
if (lastRecoveryEmailTime && Date.now() - JSON.parse(lastRecoveryEmailTime) < 60000 * 3) {
|
||||
throw new Error('Please wait before requesting another email');
|
||||
}
|
||||
!nostatus && setStatus('Password Recovery Email Sent!');
|
||||
@@ -435,13 +429,15 @@ const LoginDialog = () => {
|
||||
}, 500);
|
||||
}}
|
||||
background={!DDS.isTab ? colors.bg : null}
|
||||
transparent={true}>
|
||||
transparent={true}
|
||||
>
|
||||
{confirm && (
|
||||
<BaseDialog
|
||||
onRequestClose={() => {
|
||||
setConfirm(false);
|
||||
}}
|
||||
visible>
|
||||
visible
|
||||
>
|
||||
<DialogContainer>
|
||||
<DialogHeader
|
||||
title="Logout"
|
||||
@@ -506,7 +502,8 @@ const LoginDialog = () => {
|
||||
backgroundColor: colors.bg,
|
||||
zIndex: 10,
|
||||
minHeight: DDS.isTab ? '50%' : '85%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Header
|
||||
color="transparent"
|
||||
type="login"
|
||||
@@ -526,16 +523,16 @@ const LoginDialog = () => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: hexToRGBA(colors.red, 0.2)
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
size={20}
|
||||
style={{marginRight: 10}}
|
||||
style={{ marginRight: 10 }}
|
||||
name="information"
|
||||
color={colors.errorText}
|
||||
/>
|
||||
<Paragraph style={{maxWidth: '90%'}} color={colors.errorText}>
|
||||
Please log in to your account to access your notes on this device
|
||||
and sync them.
|
||||
<Paragraph style={{ maxWidth: '90%' }} color={colors.errorText}>
|
||||
Please log in to your account to access your notes on this device and sync them.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
@@ -550,19 +547,13 @@ const LoginDialog = () => {
|
||||
marginTop: 10,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Icon
|
||||
size={20}
|
||||
style={{marginRight: 10}}
|
||||
name="information"
|
||||
color={colors.accent}
|
||||
/>
|
||||
<Paragraph style={{maxWidth: '90%'}} color={colors.accent}>
|
||||
}}
|
||||
>
|
||||
<Icon size={20} style={{ marginRight: 10 }} name="information" color={colors.accent} />
|
||||
<Paragraph style={{ maxWidth: '90%' }} color={colors.accent}>
|
||||
When you sign up, your{' '}
|
||||
<Text style={{fontWeight: 'bold'}}>
|
||||
14 day free trial of Notesnook Pro
|
||||
</Text>{' '}
|
||||
will be activated.
|
||||
<Text style={{ fontWeight: 'bold' }}>14 day free trial of Notesnook Pro</Text> will be
|
||||
activated.
|
||||
</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
@@ -572,7 +563,8 @@ const LoginDialog = () => {
|
||||
paddingHorizontal: 12,
|
||||
paddingTop: 12,
|
||||
width: focused ? '100%' : '99.9%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{mode === MODES.changePassword ? null : (
|
||||
<Input
|
||||
fwdRef={_email}
|
||||
@@ -710,12 +702,14 @@ const LoginDialog = () => {
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={11}
|
||||
style={{
|
||||
maxWidth: '90%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
By signing up you agree to our{' '}
|
||||
<Paragraph
|
||||
size={11}
|
||||
@@ -724,7 +718,8 @@ const LoginDialog = () => {
|
||||
.catch(e => {})
|
||||
.then(r => {});
|
||||
}}
|
||||
color={colors.accent}>
|
||||
color={colors.accent}
|
||||
>
|
||||
terms of service{' '}
|
||||
</Paragraph>
|
||||
and{' '}
|
||||
@@ -735,7 +730,8 @@ const LoginDialog = () => {
|
||||
.catch(e => {})
|
||||
.then(r => {});
|
||||
}}
|
||||
color={colors.accent}>
|
||||
color={colors.accent}
|
||||
>
|
||||
privacy policy.
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
@@ -780,16 +776,17 @@ const LoginDialog = () => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon name="alert" color={colors.warningText} />
|
||||
<Paragraph
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
marginLeft: 5
|
||||
}}
|
||||
color={colors.warningText}>
|
||||
Do not close the app or move it to background while we change
|
||||
your password.
|
||||
color={colors.warningText}
|
||||
>
|
||||
Do not close the app or move it to background while we change your password.
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMenuStore, useNoteStore} from '../../provider/stores';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMenuStore, useNoteStore } from '../../provider/stores';
|
||||
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {db} from '../../utils/database';
|
||||
import {refreshNotesPage} from '../../utils/Events';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { COLORS_NOTE } from '../../utils/Colors';
|
||||
import { db } from '../../utils/database';
|
||||
import { refreshNotesPage } from '../../utils/Events';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
@@ -28,14 +24,12 @@ export const ColorSection = () => {
|
||||
}
|
||||
}, [loading]);
|
||||
|
||||
return colorNotes.map((item, index) => (
|
||||
<ColorItem key={item.id} item={item} index={index} />
|
||||
));
|
||||
return colorNotes.map((item, index) => <ColorItem key={item.id} item={item} index={index} />);
|
||||
};
|
||||
|
||||
const ColorItem = ({item, index}) => {
|
||||
const ColorItem = ({ item, index }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const setColorNotes = useMenuStore(state => state.setColorNotes);
|
||||
const [headerTextState, setHeaderTextState] = useState(null);
|
||||
const alias = db.colors.alias(item.id);
|
||||
@@ -83,17 +77,15 @@ const ColorItem = ({item, index}) => {
|
||||
if (!value || value.trim().length === 0) return;
|
||||
await db.colors.rename(item.id, value);
|
||||
setColorNotes();
|
||||
console.log('color updated')
|
||||
console.log('color updated');
|
||||
},
|
||||
positiveText:"Rename"
|
||||
positiveText: 'Rename'
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<PressableButton
|
||||
customColor={
|
||||
headerTextState?.id === item.id ? 'rgba(0,0,0,0.04)' : 'transparent'
|
||||
}
|
||||
customColor={headerTextState?.id === item.id ? 'rgba(0,0,0,0.04)' : 'transparent'}
|
||||
onLongPress={onLongPress}
|
||||
customSelectedColor={COLORS_NOTE[item.title.toLowerCase()]}
|
||||
customAlpha={!colors.night ? -0.02 : 0.02}
|
||||
@@ -109,18 +101,21 @@ const ColorItem = ({item, index}) => {
|
||||
alignItems: 'center',
|
||||
height: normalize(50),
|
||||
marginBottom: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 30,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-start'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: SIZE.lg - 2,
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {getElevation} from '../../utils';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { getElevation } from '../../utils';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import ToggleSwitch from 'toggle-switch-react-native';
|
||||
|
||||
export const MenuListItem = ({item, index, noTextMode, testID, rightBtn}) => {
|
||||
export const MenuListItem = ({ item, index, noTextMode, testID, rightBtn }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [headerTextState, setHeaderTextState] = useState(null);
|
||||
let isFocused =
|
||||
headerTextState?.id === item.name.toLowerCase() + '_navigation';
|
||||
let isFocused = headerTextState?.id === item.name.toLowerCase() + '_navigation';
|
||||
|
||||
const _onPress = event => {
|
||||
if (item.func) {
|
||||
@@ -70,12 +69,14 @@ export const MenuListItem = ({item, index, noTextMode, testID, rightBtn}) => {
|
||||
alignItems: 'center',
|
||||
height: normalize(50),
|
||||
marginBottom: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
style={{
|
||||
width: 30,
|
||||
@@ -83,13 +84,7 @@ export const MenuListItem = ({item, index, noTextMode, testID, rightBtn}) => {
|
||||
textAlign: 'left'
|
||||
}}
|
||||
name={item.icon}
|
||||
color={
|
||||
item.icon === 'crown'
|
||||
? colors.yellow
|
||||
: isFocused
|
||||
? colors.accent
|
||||
: colors.pri
|
||||
}
|
||||
color={item.icon === 'crown' ? colors.yellow : isFocused ? colors.accent : colors.pri}
|
||||
size={SIZE.lg - 2}
|
||||
/>
|
||||
{isFocused ? (
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {FlatList, View} from 'react-native';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMenuStore, useNoteStore} from '../../provider/stores';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMenuStore, useNoteStore } from '../../provider/stores';
|
||||
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOnNewTopicAdded, refreshNotesPage} from '../../utils/Events';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOnNewTopicAdded, refreshNotesPage } from '../../utils/Events';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import {ActionSheetEvent} from '../DialogManager/recievers';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { Button } from '../Button';
|
||||
import { ActionSheetEvent } from '../DialogManager/recievers';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
@@ -60,7 +56,7 @@ export const TagsSection = () => {
|
||||
type: item.type
|
||||
});
|
||||
} else {
|
||||
params = {...item, menu: true, get: 'topics'};
|
||||
params = { ...item, menu: true, get: 'topics' };
|
||||
eSendEvent(refreshNotesPage, params);
|
||||
Navigation.navigate('NotesPage', params, {
|
||||
heading: item.title,
|
||||
@@ -75,7 +71,8 @@ export const TagsSection = () => {
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<FlatList
|
||||
data={menuPins}
|
||||
style={{
|
||||
@@ -85,17 +82,15 @@ export const TagsSection = () => {
|
||||
flexGrow: 1
|
||||
}}
|
||||
keyExtractor={(item, index) => item.id}
|
||||
renderItem={({item, index}) => (
|
||||
<PinItem item={item} index={index} onPress={onPress} />
|
||||
)}
|
||||
renderItem={({ item, index }) => <PinItem item={item} index={index} onPress={onPress} />}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const PinItem = ({item, index, onPress}) => {
|
||||
const PinItem = ({ item, index, onPress }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const setMenuPins = useMenuStore(state => state.setMenuPins);
|
||||
const alias = item.type === 'tag' ? db.tags.alias(item.title) : item.title;
|
||||
const [visible, setVisible] = useState(false);
|
||||
@@ -133,7 +128,8 @@ const PinItem = ({item, index, onPress}) => {
|
||||
}}
|
||||
gestureEnabled={false}
|
||||
fwdRef={fwdRef}
|
||||
visible={true}>
|
||||
visible={true}
|
||||
>
|
||||
<Seperator />
|
||||
<Button
|
||||
title="Remove Shortcut"
|
||||
@@ -168,19 +164,22 @@ const PinItem = ({item, index, onPress}) => {
|
||||
alignItems: 'center',
|
||||
height: normalize(50),
|
||||
marginBottom: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flexGrow: 1,
|
||||
flex: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 30,
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon color={color} size={SIZE.lg - 2} name={icons[item.type]} />
|
||||
<Icon
|
||||
style={{
|
||||
@@ -198,14 +197,16 @@ const PinItem = ({item, index, onPress}) => {
|
||||
alignItems: 'flex-start',
|
||||
flexGrow: 1,
|
||||
flex: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{headerTextState?.id === item.id ? (
|
||||
<Heading
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
color={colors.heading}
|
||||
size={SIZE.md}>
|
||||
size={SIZE.md}
|
||||
>
|
||||
{alias}
|
||||
</Heading>
|
||||
) : (
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {timeSince} from '../../utils/TimeUtils';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { timeSince } from '../../utils/TimeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const TimeSince = ({time, style,updateFrequency=30000}) => {
|
||||
export const TimeSince = ({ time, style, updateFrequency = 30000 }) => {
|
||||
const [timeAgo, setTimeAgo] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
let t = timeSince(time || Date.now());
|
||||
setTimeAgo(t);
|
||||
let interval = setInterval(() => {
|
||||
@@ -17,7 +16,7 @@ export const TimeSince = ({time, style,updateFrequency=30000}) => {
|
||||
clearInterval(interval);
|
||||
interval = null;
|
||||
};
|
||||
}, [time,updateFrequency]);
|
||||
}, [time, updateFrequency]);
|
||||
|
||||
return <Paragraph style={style}>{timeAgo}</Paragraph>;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
Platform, View
|
||||
} from 'react-native';
|
||||
import { ActivityIndicator, Platform, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { useTracked } from '../../provider';
|
||||
@@ -18,7 +15,7 @@ import { TimeSince } from './TimeSince';
|
||||
|
||||
export const UserSection = () => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const user = useUserStore(state => state.user);
|
||||
const syncing = useUserStore(state => state.syncing);
|
||||
const lastSynced = useUserStore(state => state.lastSynced);
|
||||
@@ -32,13 +29,15 @@ export const UserSection = () => {
|
||||
paddingBottom: Platform.OS === 'ios' ? insets.bottom / 2 : null,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<PressableButton
|
||||
onPress={async () => {
|
||||
if (user) {
|
||||
@@ -54,18 +53,21 @@ export const UserSection = () => {
|
||||
padding: 12,
|
||||
paddingHorizontal: 20,
|
||||
borderRadius: 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
flexGrow: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
color={colors.icon}>
|
||||
color={colors.icon}
|
||||
>
|
||||
{!user ? (
|
||||
'You are not logged in'
|
||||
) : !syncing ? (
|
||||
@@ -73,7 +75,7 @@ export const UserSection = () => {
|
||||
<>
|
||||
Last synced{' '}
|
||||
<TimeSince
|
||||
style={{fontSize: SIZE.xs, color: colors.icon}}
|
||||
style={{ fontSize: SIZE.xs, color: colors.icon }}
|
||||
time={lastSynced}
|
||||
/>
|
||||
</>
|
||||
@@ -94,10 +96,9 @@ export const UserSection = () => {
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
color={colors.heading}>
|
||||
{!user
|
||||
? 'Login to sync your notes.'
|
||||
: 'Tap here to sync your notes.'}
|
||||
color={colors.heading}
|
||||
>
|
||||
{!user ? 'Login to sync your notes.' : 'Tap here to sync your notes.'}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import {FlatList, View} from 'react-native';
|
||||
import { FlatList, View } from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {useSettingStore, useUserStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import {DrawerScale} from '../../utils/Animations';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Actions } from '../../provider/Actions';
|
||||
import { useSettingStore, useUserStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import { DrawerScale } from '../../utils/Animations';
|
||||
import {
|
||||
ACCENT,
|
||||
COLOR_SCHEME,
|
||||
@@ -16,26 +16,26 @@ import {
|
||||
COLOR_SCHEME_LIGHT,
|
||||
setColorScheme
|
||||
} from '../../utils/Colors';
|
||||
import {eOpenPremiumDialog} from '../../utils/Events';
|
||||
import {MenuItemsList, SUBSCRIPTION_STATUS} from '../../utils/index';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import { eOpenPremiumDialog } from '../../utils/Events';
|
||||
import { MenuItemsList, SUBSCRIPTION_STATUS } from '../../utils/index';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import umami from '../../utils/umami';
|
||||
import {ColorSection} from './ColorSection';
|
||||
import {MenuListItem} from './MenuListItem';
|
||||
import {TagsSection} from './TagsSection';
|
||||
import {UserSection} from './UserSection';
|
||||
import { ColorSection } from './ColorSection';
|
||||
import { MenuListItem } from './MenuListItem';
|
||||
import { TagsSection } from './TagsSection';
|
||||
import { UserSection } from './UserSection';
|
||||
|
||||
export const Menu = React.memo(
|
||||
() => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const deviceMode = useSettingStore(state => state.deviceMode);
|
||||
const insets = useSafeAreaInsets();
|
||||
const user = useUserStore(state => state.user);
|
||||
const noTextMode = false;
|
||||
function changeColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
|
||||
let newColors = setColorScheme(colors, accent);
|
||||
dispatch({type: Actions.THEME, colors: newColors});
|
||||
dispatch({ type: Actions.THEME, colors: newColors });
|
||||
}
|
||||
|
||||
const BottomItemsList = [
|
||||
@@ -44,10 +44,10 @@ export const Menu = React.memo(
|
||||
icon: 'theme-light-dark',
|
||||
func: () => {
|
||||
if (!colors.night) {
|
||||
MMKV.setStringAsync('theme', JSON.stringify({night: true}));
|
||||
MMKV.setStringAsync('theme', JSON.stringify({ night: true }));
|
||||
changeColorScheme(COLOR_SCHEME_DARK);
|
||||
} else {
|
||||
MMKV.setStringAsync('theme', JSON.stringify({night: false}));
|
||||
MMKV.setStringAsync('theme', JSON.stringify({ night: false }));
|
||||
changeColorScheme(COLOR_SCHEME_LIGHT);
|
||||
}
|
||||
},
|
||||
@@ -66,7 +66,7 @@ export const Menu = React.memo(
|
||||
name: 'Notesnook Pro',
|
||||
icon: 'crown',
|
||||
func: () => {
|
||||
umami.pageView("/pro-screen","/sidemenu");
|
||||
umami.pageView('/pro-screen', '/sidemenu');
|
||||
eSendEvent(eOpenPremiumDialog);
|
||||
}
|
||||
};
|
||||
@@ -77,7 +77,8 @@ export const Menu = React.memo(
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
backgroundColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Animated.View
|
||||
style={{
|
||||
height: '100%',
|
||||
@@ -91,7 +92,8 @@ export const Menu = React.memo(
|
||||
scale: deviceMode !== 'mobile' ? 1 : DrawerScale
|
||||
}
|
||||
]
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<FlatList
|
||||
alwaysBounceVertical={false}
|
||||
contentContainerStyle={{
|
||||
@@ -108,12 +110,7 @@ export const Menu = React.memo(
|
||||
renderItem={() => (
|
||||
<>
|
||||
{MenuItemsList.map((item, index) => (
|
||||
<MenuListItem
|
||||
key={item.name}
|
||||
item={item}
|
||||
testID={item.name}
|
||||
index={index}
|
||||
/>
|
||||
<MenuListItem key={item.name} item={item} testID={item.name} index={index} />
|
||||
))}
|
||||
<ColorSection noTextMode={noTextMode} />
|
||||
<TagsSection />
|
||||
@@ -123,45 +120,34 @@ export const Menu = React.memo(
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
{!user || user?.subscription?.type === SUBSCRIPTION_STATUS.TRIAL ||
|
||||
}}
|
||||
>
|
||||
{!user ||
|
||||
user?.subscription?.type === SUBSCRIPTION_STATUS.TRIAL ||
|
||||
user?.subscription?.type === SUBSCRIPTION_STATUS.BASIC ? (
|
||||
<MenuListItem
|
||||
testID={pro.name}
|
||||
key={pro.name}
|
||||
item={pro}
|
||||
index={0}
|
||||
ignore={true}
|
||||
/>
|
||||
<MenuListItem testID={pro.name} key={pro.name} item={pro} index={0} ignore={true} />
|
||||
) : null}
|
||||
|
||||
{BottomItemsList.slice(DDS.isLargeTablet() ? 0 : 1, 3).map(
|
||||
(item, index) => (
|
||||
<MenuListItem
|
||||
testID={
|
||||
item.name == 'Night mode'
|
||||
? notesnook.ids.menu.nightmode
|
||||
: item.name
|
||||
}
|
||||
key={item.name}
|
||||
item={item}
|
||||
index={index}
|
||||
ignore={true}
|
||||
rightBtn={
|
||||
DDS.isLargeTablet() || item.name === 'Notesnook Pro'
|
||||
? null
|
||||
: BottomItemsList[0]
|
||||
}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
{BottomItemsList.slice(DDS.isLargeTablet() ? 0 : 1, 3).map((item, index) => (
|
||||
<MenuListItem
|
||||
testID={item.name == 'Night mode' ? notesnook.ids.menu.nightmode : item.name}
|
||||
key={item.name}
|
||||
item={item}
|
||||
index={index}
|
||||
ignore={true}
|
||||
rightBtn={
|
||||
DDS.isLargeTablet() || item.name === 'Notesnook Pro' ? null : BottomItemsList[0]
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
paddingHorizontal: 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<UserSection noTextMode={noTextMode} />
|
||||
</View>
|
||||
</Animated.View>
|
||||
|
||||
@@ -1,36 +1,29 @@
|
||||
import KeepAwake from '@sayem314/react-native-keep-awake';
|
||||
import {EV, EVENTS} from 'notes-core/common';
|
||||
import React, {createRef, useEffect, useState} from 'react';
|
||||
import {Modal, SafeAreaView, Text, View} from 'react-native';
|
||||
import { EV, EVENTS } from 'notes-core/common';
|
||||
import React, { createRef, useEffect, useState } from 'react';
|
||||
import { Modal, Platform, SafeAreaView, Text, View } from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import WebView from 'react-native-webview';
|
||||
import {useTracked} from '../../provider';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import Sync from '../../services/Sync';
|
||||
import {dHeight} from '../../utils';
|
||||
import {db} from '../../utils/database';
|
||||
import {
|
||||
eApplyChanges,
|
||||
eShowMergeDialog,
|
||||
refreshNotesPage
|
||||
} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import {timeConverter} from '../../utils/TimeUtils';
|
||||
import {
|
||||
getNote,
|
||||
sourceUri,
|
||||
updateNoteInEditor
|
||||
} from '../../views/Editor/Functions';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Button} from '../Button';
|
||||
import { dHeight } from '../../utils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eApplyChanges, eShowMergeDialog, refreshNotesPage } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import { timeConverter } from '../../utils/TimeUtils';
|
||||
import { getNote, sourceUri, updateNoteInEditor } from '../../views/Editor/Functions';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import DialogButtons from '../Dialog/dialog-buttons';
|
||||
import DialogContainer from '../Dialog/dialog-container';
|
||||
@@ -44,7 +37,7 @@ let note = null;
|
||||
let primaryData = null;
|
||||
let secondaryData = null;
|
||||
|
||||
function onMediaLoaded({hash, src}) {
|
||||
function onMediaLoaded({ hash, src }) {
|
||||
console.log('on media download complete');
|
||||
let inject = `
|
||||
(function(){
|
||||
@@ -58,7 +51,7 @@ function onMediaLoaded({hash, src}) {
|
||||
|
||||
const MergeEditor = () => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [primary, setPrimary] = useState(true);
|
||||
const [secondary, setSecondary] = useState(true);
|
||||
@@ -70,12 +63,9 @@ const MergeEditor = () => {
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const onPrimaryWebViewLoad = async () => {
|
||||
let content = await db.content.insertPlaceholders(
|
||||
primaryData,
|
||||
'placeholder.svg'
|
||||
);
|
||||
let content = await db.content.insertPlaceholders(primaryData, 'placeholder.svg');
|
||||
postMessage(primaryWebView, 'htmldiff', content.data);
|
||||
let theme = {...colors};
|
||||
let theme = { ...colors };
|
||||
theme.factor = normalize(1);
|
||||
|
||||
primaryWebView.current?.injectJavaScript(`
|
||||
@@ -93,12 +83,9 @@ const MergeEditor = () => {
|
||||
|
||||
const onSecondaryWebViewLoad = async () => {
|
||||
if (!secondaryData) return;
|
||||
let content = await db.content.insertPlaceholders(
|
||||
secondaryData,
|
||||
'placeholder.svg'
|
||||
);
|
||||
let content = await db.content.insertPlaceholders(secondaryData, 'placeholder.svg');
|
||||
postMessage(secondaryWebView, 'htmldiff', content?.data);
|
||||
let theme = {...colors};
|
||||
let theme = { ...colors };
|
||||
theme.factor = normalize(1);
|
||||
secondaryWebView.current?.injectJavaScript(`
|
||||
(function() {
|
||||
@@ -143,11 +130,7 @@ const MergeEditor = () => {
|
||||
const applyChanges = async () => {
|
||||
let content = keepContentFrom === 'primary' ? primaryData : secondaryData;
|
||||
let keepCopy =
|
||||
copyToSave === 'primary'
|
||||
? primaryData
|
||||
: copyToSave === 'secondary'
|
||||
? secondaryData
|
||||
: null;
|
||||
copyToSave === 'primary' ? primaryData : copyToSave === 'secondary' ? secondaryData : null;
|
||||
|
||||
await db.notes.add({
|
||||
id: note.id,
|
||||
@@ -255,8 +238,6 @@ const MergeEditor = () => {
|
||||
setDialogVisible(false);
|
||||
primaryData = null;
|
||||
secondaryData = null;
|
||||
primaryText = null;
|
||||
secondaryText = null;
|
||||
note = null;
|
||||
};
|
||||
|
||||
@@ -289,12 +270,14 @@ const MergeEditor = () => {
|
||||
'landscape-left',
|
||||
'landscape-right'
|
||||
]}
|
||||
visible={true}>
|
||||
visible={true}
|
||||
>
|
||||
<SafeAreaView
|
||||
style={{
|
||||
backgroundColor: colors.bg,
|
||||
paddingTop: insets.top
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<KeepAwake />
|
||||
{dialogVisible && (
|
||||
<BaseDialog visible={true}>
|
||||
@@ -320,7 +303,8 @@ const MergeEditor = () => {
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
backgroundColor: DDS.isLargeTablet() ? 'rgba(0,0,0,0.3)' : null
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
@@ -330,26 +314,19 @@ const MergeEditor = () => {
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 12,
|
||||
paddingLeft: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
<ActionIcon
|
||||
onPress={close}
|
||||
color={colors.pri}
|
||||
name="arrow-left"
|
||||
/>
|
||||
<Paragraph
|
||||
style={{flexWrap: 'wrap'}}
|
||||
color={colors.icon}
|
||||
size={SIZE.xs}>
|
||||
<Text style={{color: colors.accent, fontWeight: 'bold'}}>
|
||||
(This Device)
|
||||
</Text>
|
||||
}}
|
||||
>
|
||||
<ActionIcon onPress={close} color={colors.pri} name="arrow-left" />
|
||||
<Paragraph style={{ flexWrap: 'wrap' }} color={colors.icon} size={SIZE.xs}>
|
||||
<Text style={{ color: colors.accent, fontWeight: 'bold' }}>(This Device)</Text>
|
||||
{'\n'}
|
||||
{timeConverter(primaryData?.dateEdited)}
|
||||
</Paragraph>
|
||||
@@ -360,7 +337,8 @@ const MergeEditor = () => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{keepContentFrom === 'secondary' ? (
|
||||
<Button
|
||||
onPress={onPressSaveCopyFromPrimaryWebView}
|
||||
@@ -374,7 +352,7 @@ const MergeEditor = () => {
|
||||
fontSize={SIZE.xs}
|
||||
/>
|
||||
) : null}
|
||||
<View style={{width: 10}} />
|
||||
<View style={{ width: 10 }} />
|
||||
{keepContentFrom === 'secondary' ? (
|
||||
<Button
|
||||
title="Discard"
|
||||
@@ -431,7 +409,8 @@ const MergeEditor = () => {
|
||||
backgroundColor: colors.bg,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<WebView
|
||||
onLoad={onPrimaryWebViewLoad}
|
||||
ref={primaryWebView}
|
||||
@@ -467,21 +446,18 @@ const MergeEditor = () => {
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
<Paragraph
|
||||
style={{flexWrap: 'wrap'}}
|
||||
color={colors.icon}
|
||||
size={SIZE.xs}>
|
||||
<Text style={{color: 'red', fontWeight: 'bold'}}>
|
||||
(Incoming)
|
||||
</Text>
|
||||
}}
|
||||
>
|
||||
<Paragraph style={{ flexWrap: 'wrap' }} color={colors.icon} size={SIZE.xs}>
|
||||
<Text style={{ color: 'red', fontWeight: 'bold' }}>(Incoming)</Text>
|
||||
{'\n'}
|
||||
{timeConverter(secondaryData?.dateEdited)}
|
||||
</Paragraph>
|
||||
@@ -492,7 +468,8 @@ const MergeEditor = () => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-end'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{keepContentFrom === 'primary' ? (
|
||||
<Button
|
||||
height={30}
|
||||
@@ -507,7 +484,7 @@ const MergeEditor = () => {
|
||||
title="Save a copy"
|
||||
/>
|
||||
) : null}
|
||||
<View style={{width: 10}} />
|
||||
<View style={{ width: 10 }} />
|
||||
{keepContentFrom === 'primary' ? (
|
||||
<Button
|
||||
title="Discard"
|
||||
@@ -563,7 +540,8 @@ const MergeEditor = () => {
|
||||
height: dHeight / 2 - (50 + insets.top / 2),
|
||||
backgroundColor: colors.bg,
|
||||
borderRadius: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<WebView
|
||||
onLoad={onSecondaryWebViewLoad}
|
||||
ref={secondaryWebView}
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
import React, {createRef, useEffect, useState} from 'react';
|
||||
import {Keyboard, TextInput, TouchableOpacity, View} from 'react-native';
|
||||
import {FlatList} from 'react-native-gesture-handler';
|
||||
import React, { createRef, useEffect, useState } from 'react';
|
||||
import { Keyboard, TextInput, TouchableOpacity, View } from 'react-native';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {
|
||||
useNotebookStore,
|
||||
useSelectionStore,
|
||||
useSettingStore
|
||||
} from '../../provider/stores';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Actions } from '../../provider/Actions';
|
||||
import { useNotebookStore, useSelectionStore, useSettingStore } from '../../provider/stores';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
@@ -17,20 +13,20 @@ import {
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {getTotalNotes, InteractionManager} from '../../utils';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOpenMoveNoteDialog} from '../../utils/Events';
|
||||
import {pv, SIZE} from '../../utils/SizeUtils';
|
||||
import { getTotalNotes, InteractionManager } from '../../utils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenMoveNoteDialog } from '../../utils/Events';
|
||||
import { pv, SIZE } from '../../utils/SizeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import Input from '../Input';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Dialog} from '../Dialog';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Dialog } from '../Dialog';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import layoutmanager from '../../utils/layout-manager';
|
||||
|
||||
let newNotebookTitle = null;
|
||||
@@ -85,13 +81,11 @@ const MoveNoteDialog = () => {
|
||||
|
||||
export default MoveNoteDialog;
|
||||
|
||||
const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
const MoveNoteComponent = ({ close, note, setNote }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const nbs = useNotebookStore(state =>
|
||||
state.notebooks.filter(n => n?.type === 'notebook')
|
||||
);
|
||||
const nbs = useNotebookStore(state => state.notebooks.filter(n => n?.type === 'notebook'));
|
||||
let notebooks = [...db.notebooks.all];
|
||||
|
||||
const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
|
||||
@@ -140,13 +134,10 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
|
||||
const handlePress = async (item, index) => {
|
||||
if (note && item.notes.indexOf(note.id) > -1) {
|
||||
await db.notebooks
|
||||
.notebook(item.notebookId)
|
||||
.topics.topic(item.id)
|
||||
.delete(note.id);
|
||||
await db.notebooks.notebook(item.notebookId).topics.topic(item.id).delete(note.id);
|
||||
|
||||
if (note && note.id) {
|
||||
setNote({...db.notes.note(note.id).data});
|
||||
setNote({ ...db.notes.note(note.id).data });
|
||||
requestAnimationFrame(() => {
|
||||
//layoutmanager.withSpringAnimation(500);
|
||||
Navigation.setRoutesToUpdate([
|
||||
@@ -173,7 +164,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
...noteIds
|
||||
);
|
||||
if (note && note.id) {
|
||||
setNote({...db.notes.note(note.id).data});
|
||||
setNote({ ...db.notes.note(note.id).data });
|
||||
requestAnimationFrame(() => {
|
||||
//layoutmanager.withSpringAnimation(500);
|
||||
Navigation.setRoutesToUpdate([
|
||||
@@ -240,7 +231,8 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
paddingHorizontal: 12,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Add to notebook"
|
||||
paragraph={`Add your notes to notebooks to find them easily.`}
|
||||
@@ -273,7 +265,8 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
style={{
|
||||
width: '100%',
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
fwdRef={notebookInput}
|
||||
onChangeText={value => {
|
||||
@@ -290,7 +283,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
button={{
|
||||
icon: 'check',
|
||||
color: notebookInputFocused ? colors.accent : colors.icon,
|
||||
onPress:addNewNotebook
|
||||
onPress: addNewNotebook
|
||||
}}
|
||||
onSubmit={addNewNotebook}
|
||||
placeholder="Create a new notebook"
|
||||
@@ -300,7 +293,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}
|
||||
renderItem={({item, index}) => (
|
||||
renderItem={({ item, index }) => (
|
||||
<View
|
||||
style={{
|
||||
borderWidth: 1,
|
||||
@@ -308,7 +301,8 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
borderRadius: 6,
|
||||
overflow: 'hidden',
|
||||
marginBottom: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<PressableButton
|
||||
onPress={() => {
|
||||
if (!item.topics || item.topics.length === 0) {
|
||||
@@ -326,7 +320,8 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
width: '100%',
|
||||
borderRadius: 5,
|
||||
alignItems: 'flex-start'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
@@ -335,13 +330,13 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<Heading
|
||||
color={
|
||||
noteExists.indexOf(item.id) > -1 ? colors.accent : null
|
||||
}
|
||||
size={SIZE.md}>
|
||||
color={noteExists.indexOf(item.id) > -1 ? colors.accent : null}
|
||||
size={SIZE.md}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
{item.topics?.length > 0 ? (
|
||||
@@ -391,7 +386,7 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
alignSelf: 'flex-end',
|
||||
maxHeight: 500
|
||||
}}
|
||||
renderItem={({item, index}) => (
|
||||
renderItem={({ item, index }) => (
|
||||
<PressableButton
|
||||
onPress={() => handlePress(item, index)}
|
||||
type="gray"
|
||||
@@ -405,11 +400,10 @@ const MoveNoteComponent = ({close, note, setNote}) => {
|
||||
flexDirection: 'row',
|
||||
paddingHorizontal: 12,
|
||||
justifyContent: 'space-between'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View>
|
||||
<Paragraph color={colors.heading}>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
<Paragraph color={colors.heading}>{item.title}</Paragraph>
|
||||
<Paragraph color={colors.icon} size={SIZE.xs}>
|
||||
{item.notes.length + ' notes'}
|
||||
</Paragraph>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
import React, {useCallback, useEffect, useState} from 'react';
|
||||
import {Text, View} from 'react-native';
|
||||
import {FlatList} from 'react-native-gesture-handler';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {presentSheet} from '../../services/EventManager';
|
||||
import {db} from '../../utils/database';
|
||||
import { useTracked } from '../../provider';
|
||||
import { presentSheet } from '../../services/EventManager';
|
||||
import { db } from '../../utils/database';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {timeConverter, timeSince} from '../../utils/TimeUtils';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { timeConverter, timeSince } from '../../utils/TimeUtils';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import GeneralSheet from '../GeneralSheet';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Seperator from '../Seperator';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import NotePreview from './preview';
|
||||
|
||||
export default function NoteHistory({note, ref}) {
|
||||
export default function NoteHistory({ note, ref }) {
|
||||
const [history, setHistory] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
@@ -41,7 +41,7 @@ export default function NoteHistory({note, ref}) {
|
||||
content={content}
|
||||
/>
|
||||
),
|
||||
context: 'note_history',
|
||||
context: 'note_history'
|
||||
});
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ export default function NoteHistory({note, ref}) {
|
||||
};
|
||||
|
||||
const renderItem = useCallback(
|
||||
({item, index}) => (
|
||||
({ item, index }) => (
|
||||
<PressableButton
|
||||
type="grayBg"
|
||||
onPress={() => preview(item)}
|
||||
@@ -69,7 +69,8 @@ export default function NoteHistory({note, ref}) {
|
||||
height: 45,
|
||||
marginBottom: 10,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph>{getDate(item.dateCreated, item.dateModified)}</Paragraph>
|
||||
<Paragraph color={colors.icon} size={SIZE.xs}>
|
||||
{timeSince(item.dateModified)}
|
||||
@@ -106,11 +107,10 @@ export default function NoteHistory({note, ref}) {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 200
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="history" size={60} color={colors.icon} />
|
||||
<Paragraph color={colors.icon}>
|
||||
No note history found on this device.
|
||||
</Paragraph>
|
||||
<Paragraph color={colors.icon}>No note history found on this device.</Paragraph>
|
||||
</View>
|
||||
}
|
||||
renderItem={renderItem}
|
||||
@@ -120,13 +120,15 @@ export default function NoteHistory({note, ref}) {
|
||||
color={colors.icon}
|
||||
style={{
|
||||
alignSelf: 'center'
|
||||
}}>
|
||||
Note version history is local only.{' '}
|
||||
<Text
|
||||
onPress={() => {
|
||||
openLinkInBrowser("https://docs.notesnook.com/versionhistory",colors);
|
||||
}}
|
||||
style={{color: colors.accent, textDecorationLine: 'underline'}}>
|
||||
>
|
||||
Note version history is local only.{' '}
|
||||
<Text
|
||||
onPress={() => {
|
||||
openLinkInBrowser('https://docs.notesnook.com/versionhistory', colors);
|
||||
}}
|
||||
style={{ color: colors.accent, textDecorationLine: 'underline' }}
|
||||
>
|
||||
Learn how this works.
|
||||
</Text>
|
||||
</Paragraph>
|
||||
|
||||
@@ -1,33 +1,30 @@
|
||||
import React, {useRef} from 'react';
|
||||
import {Alert, Platform, View} from 'react-native';
|
||||
import React, { useRef } from 'react';
|
||||
import { Alert, Platform, View } from 'react-native';
|
||||
import WebView from 'react-native-webview';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useEditorStore} from '../../provider/stores';
|
||||
import {eSendEvent, ToastEvent} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useEditorStore } from '../../provider/stores';
|
||||
import { eSendEvent, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {eCloseProgressDialog, eOnLoadNote} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {normalize} from '../../utils/SizeUtils';
|
||||
import {getNote, sourceUri} from '../../views/Editor/Functions';
|
||||
import { db } from '../../utils/database';
|
||||
import { eCloseProgressDialog, eOnLoadNote } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { normalize } from '../../utils/SizeUtils';
|
||||
import { getNote, sourceUri } from '../../views/Editor/Functions';
|
||||
import tiny from '../../views/Editor/tiny/tiny';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Button} from '../Button';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export default function NotePreview({session, content}) {
|
||||
export default function NotePreview({ session, content }) {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const webviewRef = useRef();
|
||||
|
||||
const onLoad = async () => {
|
||||
let preview = await db.content.insertPlaceholders(
|
||||
content,
|
||||
'placeholder.svg'
|
||||
);
|
||||
let preview = await db.content.insertPlaceholders(content, 'placeholder.svg');
|
||||
|
||||
let theme = {...colors};
|
||||
let theme = { ...colors };
|
||||
theme.factor = normalize(1);
|
||||
|
||||
webviewRef.current?.injectJavaScript(`
|
||||
@@ -77,7 +74,7 @@ export default function NotePreview({session, content}) {
|
||||
await db.noteHistory.restore(session.id);
|
||||
if (useEditorStore.getState()?.currentEditingNote === session?.noteId) {
|
||||
if (getNote()) {
|
||||
eSendEvent(eOnLoadNote, {...getNote(), forced: true});
|
||||
eSendEvent(eOnLoadNote, { ...getNote(), forced: true });
|
||||
}
|
||||
}
|
||||
eSendEvent(eCloseProgressDialog, 'note_history');
|
||||
@@ -99,7 +96,8 @@ export default function NotePreview({session, content}) {
|
||||
style={{
|
||||
height: session.locked ? null : 600,
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader padding={12} title={session.session} />
|
||||
{!session.locked ? (
|
||||
<WebView
|
||||
@@ -138,23 +136,18 @@ export default function NotePreview({session, content}) {
|
||||
height: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<Paragraph color={colors.icon}>
|
||||
Preview not available, content is encrypted.
|
||||
</Paragraph>
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.icon}>Preview not available, content is encrypted.</Paragraph>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
<Button
|
||||
onPress={restore}
|
||||
title="Restore this version"
|
||||
type="accent"
|
||||
width="100%"
|
||||
/>
|
||||
}}
|
||||
>
|
||||
<Button onPress={restore} title="Restore this version" type="accent" width="100%" />
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import {decode, EntityLevel} from 'entities';
|
||||
import React, {useEffect} from 'react';
|
||||
import {Platform, View} from 'react-native';
|
||||
import { decode, EntityLevel } from 'entities';
|
||||
import React, { useEffect } from 'react';
|
||||
import { Platform, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useSettingStore, useTagStore} from '../../provider/stores';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSettingStore, useTagStore } from '../../provider/stores';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {db} from '../../utils/database';
|
||||
import {refreshNotesPage} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Button} from '../Button';
|
||||
import {ActionSheetEvent} from '../DialogManager/recievers';
|
||||
import {TimeSince} from '../Menu/TimeSince';
|
||||
import {Properties} from '../Properties';
|
||||
import { COLORS_NOTE } from '../../utils/Colors';
|
||||
import { db } from '../../utils/database';
|
||||
import { refreshNotesPage } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import { ActionSheetEvent } from '../DialogManager/recievers';
|
||||
import { TimeSince } from '../Menu/TimeSince';
|
||||
import { Properties } from '../Properties';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
const navigateToTopic = topic => {
|
||||
let routeName = 'NotesPage';
|
||||
let params = {...topic, menu: false, get: 'topics'};
|
||||
let params = { ...topic, menu: false, get: 'topics' };
|
||||
let headerState = {
|
||||
heading: topic.title,
|
||||
id: topic.id,
|
||||
@@ -52,15 +52,9 @@ const showActionSheet = item => {
|
||||
Properties.present(item);
|
||||
};
|
||||
|
||||
const NoteItem = ({
|
||||
item,
|
||||
isTrash,
|
||||
tags,
|
||||
dateBy = 'dateCreated',
|
||||
noOpen = false
|
||||
}) => {
|
||||
const NoteItem = ({ item, isTrash, tags, dateBy = 'dateCreated', noOpen = false }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const settings = useSettingStore(state => state.settings);
|
||||
const compactMode = settings.notesListMode === 'compact';
|
||||
const attachmentCount = db.attachments?.ofNote(item.id, 'all')?.length || 0;
|
||||
@@ -68,7 +62,7 @@ const NoteItem = ({
|
||||
function getNotebook() {
|
||||
if (isTrash || !item.notebooks || item.notebooks.length < 1) return [];
|
||||
let item_notebook = item.notebooks?.slice(0, 1)[0];
|
||||
notebook = db.notebooks.notebook(item_notebook.id);
|
||||
let notebook = db.notebooks.notebook(item_notebook.id);
|
||||
|
||||
if (!notebook) return [];
|
||||
let topic = notebook.topics.topic(item_notebook.topics[0])?._topic;
|
||||
@@ -92,7 +86,8 @@ const NoteItem = ({
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{!compactMode ? (
|
||||
<View
|
||||
style={{
|
||||
@@ -101,7 +96,8 @@ const NoteItem = ({
|
||||
zIndex: 10,
|
||||
elevation: 10,
|
||||
marginBottom: 2.5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{getNotebook().map(_item => (
|
||||
<Button
|
||||
title={_item.title}
|
||||
@@ -133,7 +129,8 @@ const NoteItem = ({
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
size={SIZE.md}>
|
||||
size={SIZE.md}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
|
||||
@@ -142,7 +139,8 @@ const NoteItem = ({
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
numberOfLines={2}>
|
||||
numberOfLines={2}
|
||||
>
|
||||
{decode(item.headline, {
|
||||
level: EntityLevel.HTML
|
||||
})}
|
||||
@@ -157,7 +155,8 @@ const NoteItem = ({
|
||||
width: '100%',
|
||||
marginTop: 5,
|
||||
height: SIZE.md + 2
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{!isTrash ? (
|
||||
<>
|
||||
{item.conflicted ? (
|
||||
@@ -177,9 +176,7 @@ const NoteItem = ({
|
||||
marginRight: 6
|
||||
}}
|
||||
time={item[dateBy]}
|
||||
updateFrequency={
|
||||
Date.now() - item[dateBy] < 60000 ? 2000 : 60000
|
||||
}
|
||||
updateFrequency={Date.now() - item[dateBy] < 60000 ? 2000 : 60000}
|
||||
/>
|
||||
|
||||
{attachmentCount > 0 ? (
|
||||
@@ -188,7 +185,8 @@ const NoteItem = ({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="attachment" size={SIZE.md} color={colors.icon} />
|
||||
<Paragraph color={colors.icon} size={SIZE.xs}>
|
||||
{attachmentCount}
|
||||
@@ -204,9 +202,7 @@ const NoteItem = ({
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}
|
||||
color={
|
||||
COLORS_NOTE[item.color?.toLowerCase()] || colors.accent
|
||||
}
|
||||
color={COLORS_NOTE[item.color?.toLowerCase()] || colors.accent}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
@@ -244,7 +240,7 @@ const NoteItem = ({
|
||||
textStyle={{
|
||||
textDecorationLine: 'underline'
|
||||
}}
|
||||
hitSlop={{top: 8, bottom: 12, left: 0, right: 0}}
|
||||
hitSlop={{ top: 8, bottom: 12, left: 0, right: 0 }}
|
||||
fontSize={SIZE.xs}
|
||||
style={{
|
||||
borderRadius: 5,
|
||||
@@ -266,7 +262,8 @@ const NoteItem = ({
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Deleted on{' '}
|
||||
{item && item.dateDeleted
|
||||
? new Date(item.dateDeleted).toISOString().slice(0, 10)
|
||||
@@ -278,7 +275,8 @@ const NoteItem = ({
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.itemType[0].toUpperCase() + item.itemType.slice(1)}
|
||||
</Paragraph>
|
||||
</>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React from 'react';
|
||||
import NoteItem from '.';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useSelectionStore, useTrashStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSendEvent, openVault, ToastEvent} from '../../services/EventManager';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useSelectionStore, useTrashStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent, openVault, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {history} from '../../utils';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOnLoadNote, eShowMergeDialog} from '../../utils/Events';
|
||||
import {tabBarRef} from '../../utils/Refs';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import { history } from '../../utils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOnLoadNote, eShowMergeDialog } from '../../utils/Events';
|
||||
import { tabBarRef } from '../../utils/Refs';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import SelectionWrapper from '../SelectionWrapper';
|
||||
|
||||
export const NoteWrapper = React.memo(
|
||||
({item, index, tags, compactMode, dateBy}) => {
|
||||
({ item, index, tags, dateBy }) => {
|
||||
const isTrash = item.type === 'trash';
|
||||
const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
|
||||
const onPress = async () => {
|
||||
@@ -92,13 +92,14 @@ export const NoteWrapper = React.memo(
|
||||
height={100}
|
||||
testID={notesnook.ids.note.get(index)}
|
||||
onPress={onPress}
|
||||
item={item}>
|
||||
item={item}
|
||||
>
|
||||
<NoteItem item={item} dateBy={dateBy} tags={tags} isTrash={isTrash} />
|
||||
</SelectionWrapper>
|
||||
);
|
||||
},
|
||||
(prev, next) => {
|
||||
if (prev.dateBy !== next.dateBy ) {
|
||||
if (prev.dateBy !== next.dateBy) {
|
||||
return false;
|
||||
}
|
||||
if (prev.item?.dateEdited !== next.item?.dateEdited) {
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useSettingStore} from '../../provider/stores';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSettingStore } from '../../provider/stores';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {getTotalNotes, history} from '../../utils';
|
||||
import {refreshNotesPage} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Button} from '../Button';
|
||||
import {ActionSheetEvent} from '../DialogManager/recievers';
|
||||
import { getTotalNotes, history } from '../../utils';
|
||||
import { refreshNotesPage } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import { ActionSheetEvent } from '../DialogManager/recievers';
|
||||
import { Properties } from '../Properties';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const NotebookItem = ({
|
||||
item,
|
||||
isTopic = false,
|
||||
notebookID,
|
||||
isTrash,
|
||||
dateBy
|
||||
}) => {
|
||||
export const NotebookItem = ({ item, isTopic = false, notebookID, isTrash, dateBy }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const settings = useSettingStore(state => state.settings);
|
||||
const compactMode = settings.notebooksListMode === 'compact';
|
||||
const topics = item.topics?.slice(0, 3) || [];
|
||||
@@ -36,7 +30,7 @@ export const NotebookItem = ({
|
||||
const navigateToTopic = topic => {
|
||||
if (history.selectedItemsList.length > 0) return;
|
||||
let routeName = 'NotesPage';
|
||||
let params = {...topic, menu: false, get: 'topics'};
|
||||
let params = { ...topic, menu: false, get: 'topics' };
|
||||
let headerState = {
|
||||
heading: topic.title,
|
||||
id: topic.id,
|
||||
@@ -52,13 +46,15 @@ export const NotebookItem = ({
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
size={SIZE.md}
|
||||
numberOfLines={1}
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
{isTopic || !item.description || compactMode ? null : (
|
||||
@@ -67,7 +63,8 @@ export const NotebookItem = ({
|
||||
numberOfLines={2}
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.description}
|
||||
</Paragraph>
|
||||
)}
|
||||
@@ -78,7 +75,8 @@ export const NotebookItem = ({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
flexWrap: 'wrap'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{topics.map(topic => (
|
||||
<Button
|
||||
title={topic.title}
|
||||
@@ -86,14 +84,12 @@ export const NotebookItem = ({
|
||||
height={null}
|
||||
textStyle={{
|
||||
fontWeight: 'normal',
|
||||
fontFamily: null
|
||||
fontFamily: null,
|
||||
marginRight: 0
|
||||
}}
|
||||
type="grayBg"
|
||||
fontSize={SIZE.xs}
|
||||
icon="bookmark-outline"
|
||||
textStyle={{
|
||||
marginRight: 0
|
||||
}}
|
||||
iconSize={SIZE.sm}
|
||||
style={{
|
||||
borderRadius: 5,
|
||||
@@ -118,13 +114,15 @@ export const NotebookItem = ({
|
||||
alignItems: 'center',
|
||||
marginTop: 5,
|
||||
height: SIZE.md + 2
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
color={colors.accent}
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{isTopic ? 'Topic' : 'Notebook'}
|
||||
</Paragraph>
|
||||
|
||||
@@ -136,9 +134,9 @@ export const NotebookItem = ({
|
||||
style={{
|
||||
textAlignVertical: 'center',
|
||||
marginRight: 6
|
||||
}}>
|
||||
{'Deleted on ' +
|
||||
new Date(item.dateDeleted).toISOString().slice(0, 10)}
|
||||
}}
|
||||
>
|
||||
{'Deleted on ' + new Date(item.dateDeleted).toISOString().slice(0, 10)}
|
||||
</Paragraph>
|
||||
<Paragraph
|
||||
color={colors.accent}
|
||||
@@ -146,7 +144,8 @@ export const NotebookItem = ({
|
||||
style={{
|
||||
textAlignVertical: 'center',
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.itemType[0].toUpperCase() + item.itemType.slice(1)}
|
||||
</Paragraph>
|
||||
</>
|
||||
@@ -156,7 +155,8 @@ export const NotebookItem = ({
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{new Date(item[dateBy]).toDateString().substring(4)}
|
||||
</Paragraph>
|
||||
)}
|
||||
@@ -165,7 +165,8 @@ export const NotebookItem = ({
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
marginRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item && totalNotes > 1
|
||||
? totalNotes + ' notes'
|
||||
: totalNotes === 1
|
||||
@@ -175,7 +176,6 @@ export const NotebookItem = ({
|
||||
|
||||
{item.pinned ? (
|
||||
<Icon
|
||||
style={{marginRight: 6}}
|
||||
name="pin-outline"
|
||||
size={SIZE.sm}
|
||||
style={{
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import {NotebookItem} from '.';
|
||||
import {useSelectionStore} from '../../provider/stores';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { NotebookItem } from '.';
|
||||
import { useSelectionStore } from '../../provider/stores';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {history} from '../../utils';
|
||||
import {eOnNewTopicAdded, refreshNotesPage} from '../../utils/Events';
|
||||
import { history } from '../../utils';
|
||||
import { eOnNewTopicAdded, refreshNotesPage } from '../../utils/Events';
|
||||
import SelectionWrapper from '../SelectionWrapper';
|
||||
|
||||
export const NotebookWrapper = React.memo(
|
||||
({item, index,dateBy}) => {
|
||||
({ item, index, dateBy }) => {
|
||||
const isTrash = item.type === 'trash';
|
||||
const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
|
||||
|
||||
@@ -23,7 +23,7 @@ export const NotebookWrapper = React.memo(
|
||||
|
||||
let params =
|
||||
item.type === 'topic'
|
||||
? {...item, menu: false}
|
||||
? { ...item, menu: false }
|
||||
: {
|
||||
menu: false,
|
||||
notebook: item,
|
||||
@@ -47,7 +47,8 @@ export const NotebookWrapper = React.memo(
|
||||
index={index}
|
||||
onPress={onPress}
|
||||
height={item.type === 'topic' ? 80 : 110}
|
||||
item={item}>
|
||||
item={item}
|
||||
>
|
||||
<NotebookItem
|
||||
isTopic={item.type === 'topic'}
|
||||
item={item}
|
||||
@@ -59,7 +60,7 @@ export const NotebookWrapper = React.memo(
|
||||
);
|
||||
},
|
||||
(prev, next) => {
|
||||
if (prev.dateBy !== next.dateBy ) {
|
||||
if (prev.dateBy !== next.dateBy) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,68 +1,68 @@
|
||||
import React from 'react';
|
||||
import {ScrollView} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {FeatureBlock} from './feature';
|
||||
import { ScrollView } from 'react-native';
|
||||
import { FeatureBlock } from './feature';
|
||||
|
||||
export const CompactFeatures = ({vertical,features = [],maxHeight=500,scrollRef}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
let data = vertical ? features : [
|
||||
{
|
||||
highlight: 'Everything',
|
||||
content: 'in basic',
|
||||
icon: 'emoticon-wink'
|
||||
},
|
||||
{
|
||||
highlight: 'Unlimited',
|
||||
content: 'notebooks',
|
||||
icon: 'notebook'
|
||||
},
|
||||
{
|
||||
highlight: 'File & image',
|
||||
content: 'attachments',
|
||||
icon: 'attachment'
|
||||
},
|
||||
{
|
||||
highlight: 'Instant',
|
||||
content: 'syncing',
|
||||
icon: 'sync'
|
||||
},
|
||||
{
|
||||
highlight: 'Private',
|
||||
content: 'vault',
|
||||
icon: 'shield'
|
||||
},
|
||||
{
|
||||
highlight: 'Rich text',
|
||||
content: 'editing',
|
||||
icon: 'square-edit-outline'
|
||||
},
|
||||
{
|
||||
highlight: 'PDF & markdown',
|
||||
content: 'exports',
|
||||
icon: 'file'
|
||||
},
|
||||
{
|
||||
highlight: 'Encrypted',
|
||||
content: 'backups',
|
||||
icon: 'backup-restore'
|
||||
}
|
||||
]
|
||||
export const CompactFeatures = ({ vertical, features = [], maxHeight = 500, scrollRef }) => {
|
||||
let data = vertical
|
||||
? features
|
||||
: [
|
||||
{
|
||||
highlight: 'Everything',
|
||||
content: 'in basic',
|
||||
icon: 'emoticon-wink'
|
||||
},
|
||||
{
|
||||
highlight: 'Unlimited',
|
||||
content: 'notebooks',
|
||||
icon: 'notebook'
|
||||
},
|
||||
{
|
||||
highlight: 'File & image',
|
||||
content: 'attachments',
|
||||
icon: 'attachment'
|
||||
},
|
||||
{
|
||||
highlight: 'Instant',
|
||||
content: 'syncing',
|
||||
icon: 'sync'
|
||||
},
|
||||
{
|
||||
highlight: 'Private',
|
||||
content: 'vault',
|
||||
icon: 'shield'
|
||||
},
|
||||
{
|
||||
highlight: 'Rich text',
|
||||
content: 'editing',
|
||||
icon: 'square-edit-outline'
|
||||
},
|
||||
{
|
||||
highlight: 'PDF & markdown',
|
||||
content: 'exports',
|
||||
icon: 'file'
|
||||
},
|
||||
{
|
||||
highlight: 'Encrypted',
|
||||
content: 'backups',
|
||||
icon: 'backup-restore'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
horizontal={!vertical}
|
||||
nestedScrollEnabled
|
||||
onMomentumScrollEnd={() => {
|
||||
scrollRef?.current?.handleChildScrollEnd();
|
||||
}}
|
||||
nestedScrollEnabled
|
||||
onMomentumScrollEnd={() => {
|
||||
scrollRef?.current?.handleChildScrollEnd();
|
||||
}}
|
||||
showsHorizontalScrollIndicator={false}
|
||||
style={{
|
||||
width: '100%',
|
||||
maxHeight:maxHeight
|
||||
}}>
|
||||
maxHeight: maxHeight
|
||||
}}
|
||||
>
|
||||
{data.map(item => (
|
||||
<FeatureBlock vertical={vertical} {...item} />
|
||||
<FeatureBlock key={item.highlight} vertical={vertical} {...item} />
|
||||
))}
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import React, {useState} from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import {LAUNCH_ROCKET} from '../../assets/images/assets';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useUserStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSendEvent, presentSheet} from '../../services/EventManager';
|
||||
import {getElevation} from '../../utils';
|
||||
import {eOpenLoginDialog} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import React, { useState } from 'react';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { LAUNCH_ROCKET } from '../../assets/images/assets';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useUserStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent, presentSheet } from '../../services/EventManager';
|
||||
import { getElevation } from '../../utils';
|
||||
import { eOpenLoginDialog } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import umami from '../../utils/umami';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {Button} from '../Button';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import GeneralSheet from '../GeneralSheet';
|
||||
import {SvgToPngView} from '../ListPlaceholders';
|
||||
import { SvgToPngView } from '../ListPlaceholders';
|
||||
import Seperator from '../Seperator';
|
||||
import {Toast} from '../Toast';
|
||||
import { Toast } from '../Toast';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {features} from './features';
|
||||
import {Group} from './group';
|
||||
import {PricingPlans} from './pricing-plans';
|
||||
import { features } from './features';
|
||||
import { Group } from './group';
|
||||
import { PricingPlans } from './pricing-plans';
|
||||
|
||||
export const Component = ({close, promo, getRef}) => {
|
||||
export const Component = ({ close, promo, getRef }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const colors = state.colors;
|
||||
const user = useUserStore(state => state.user);
|
||||
@@ -63,7 +63,8 @@ export const Component = ({close, promo, getRef}) => {
|
||||
justifyContent: 'space-between',
|
||||
borderRadius: 10,
|
||||
maxHeight: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<GeneralSheet context="pricing_plans" />
|
||||
<ActionIcon
|
||||
onPress={() => {
|
||||
@@ -87,7 +88,8 @@ export const Component = ({close, promo, getRef}) => {
|
||||
}}
|
||||
keyboardDismissMode="none"
|
||||
keyboardShouldPersistTaps="always"
|
||||
onScroll={onScroll}>
|
||||
onScroll={onScroll}
|
||||
>
|
||||
<View
|
||||
key="top-banner"
|
||||
style={{
|
||||
@@ -95,12 +97,9 @@ export const Component = ({close, promo, getRef}) => {
|
||||
alignItems: 'center',
|
||||
height: 400,
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<SvgToPngView
|
||||
width={350}
|
||||
height={350}
|
||||
src={LAUNCH_ROCKET(colors.accent)}
|
||||
/>
|
||||
}}
|
||||
>
|
||||
<SvgToPngView width={350} height={350} src={LAUNCH_ROCKET(colors.accent)} />
|
||||
</View>
|
||||
|
||||
<Heading
|
||||
@@ -109,7 +108,8 @@ export const Component = ({close, promo, getRef}) => {
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
paddingTop: 20
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Notesnook{' '}
|
||||
<Heading size={SIZE.lg} color={colors.accent}>
|
||||
Pro
|
||||
@@ -124,16 +124,15 @@ export const Component = ({close, promo, getRef}) => {
|
||||
alignSelf: 'center',
|
||||
paddingBottom: 20,
|
||||
width: '90%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Ready to take the next step on your private note taking journey?
|
||||
</Paragraph>
|
||||
|
||||
<Button
|
||||
key="calltoaction"
|
||||
onPress={onPress}
|
||||
title={
|
||||
promo ? promo.text : user ? `See all plans` : 'Try free for 14 days'
|
||||
}
|
||||
title={promo ? promo.text : user ? `See all plans` : 'Try free for 14 days'}
|
||||
type="accent"
|
||||
style={{
|
||||
paddingHorizontal: 24,
|
||||
@@ -151,7 +150,8 @@ export const Component = ({close, promo, getRef}) => {
|
||||
key="plans"
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<PricingPlans promo={promo} />
|
||||
</View>
|
||||
</ScrollView>
|
||||
@@ -159,9 +159,7 @@ export const Component = ({close, promo, getRef}) => {
|
||||
{floatingButton ? (
|
||||
<Button
|
||||
onPress={onPress}
|
||||
title={
|
||||
promo ? promo.text : user ? `See all plans` : 'Try free for 14 days'
|
||||
}
|
||||
title={promo ? promo.text : user ? `See all plans` : 'Try free for 14 days'}
|
||||
type="accent"
|
||||
style={{
|
||||
paddingHorizontal: 24,
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import PremiumService from '../../services/PremiumService';
|
||||
import {
|
||||
eOpenPremiumDialog,
|
||||
eOpenResultDialog,
|
||||
eOpenTrialEndingDialog
|
||||
} from '../../utils/Events';
|
||||
import { eOpenPremiumDialog, eOpenResultDialog, eOpenTrialEndingDialog } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { Button } from '../Button';
|
||||
@@ -25,17 +17,19 @@ import { Offer } from './offer';
|
||||
|
||||
export const Expiring = () => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [status, setStatus] = useState({
|
||||
title: 'Your trial is ending soon',
|
||||
offer: null,
|
||||
extend: true
|
||||
});
|
||||
const promo = status.offer ? {
|
||||
promoCode:"com.streetwriters.notesnook.sub.yr.trialoffer",
|
||||
text:"GET 30% OFF on yearly"
|
||||
}: null
|
||||
const promo = status.offer
|
||||
? {
|
||||
promoCode: 'com.streetwriters.notesnook.sub.yr.trialoffer',
|
||||
text: 'GET 30% OFF on yearly'
|
||||
}
|
||||
: null;
|
||||
|
||||
useEffect(() => {
|
||||
eSubscribeEvent(eOpenTrialEndingDialog, open);
|
||||
@@ -54,24 +48,28 @@ export const Expiring = () => {
|
||||
<BaseDialog
|
||||
onRequestClose={() => {
|
||||
setVisible(false);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogContainer>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
textBreakStrategy="balanced"
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
paddingTop: 18
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{status.title}
|
||||
</Heading>
|
||||
<Seperator />
|
||||
@@ -79,7 +77,8 @@ export const Expiring = () => {
|
||||
style={{
|
||||
width: '100%',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{status.offer ? (
|
||||
<>
|
||||
<Offer padding={20} off={status.offer} />
|
||||
@@ -93,14 +92,14 @@ export const Expiring = () => {
|
||||
paddingTop: 0,
|
||||
paddingBottom: 20
|
||||
}}
|
||||
size={SIZE.md + 2}>
|
||||
Upgrade now to continue using all the pro features after
|
||||
your trial ends
|
||||
size={SIZE.md + 2}
|
||||
>
|
||||
Upgrade now to continue using all the pro features after your trial ends
|
||||
</Paragraph>
|
||||
</>
|
||||
)}
|
||||
|
||||
<CompactFeatures/>
|
||||
<CompactFeatures />
|
||||
|
||||
<Paragraph
|
||||
onPress={async () => {
|
||||
@@ -113,7 +112,8 @@ export const Expiring = () => {
|
||||
textDecorationLine: 'underline',
|
||||
color: colors.icon,
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
See what's included in Basic & Pro plans
|
||||
</Paragraph>
|
||||
|
||||
@@ -127,14 +127,15 @@ export const Expiring = () => {
|
||||
width: '100%',
|
||||
borderBottomRightRadius: 10,
|
||||
borderBottomLeftRadius: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="transparent"
|
||||
title="Subscribe now"
|
||||
onPress={async () => {
|
||||
setVisible(false);
|
||||
await sleep(300);
|
||||
PremiumService.sheet(null,promo)
|
||||
PremiumService.sheet(null, promo);
|
||||
}}
|
||||
fontSize={SIZE.md + 2}
|
||||
style={{
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import React from 'react';
|
||||
import {Text, View} from 'react-native';
|
||||
import {color} from 'react-native-reanimated';
|
||||
import { Text, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import Seperator from '../Seperator';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {ProTag} from './pro-tag';
|
||||
import { ProTag } from './pro-tag';
|
||||
|
||||
export const FeatureBlock = ({
|
||||
vertical,
|
||||
highlight,
|
||||
content,
|
||||
icon,
|
||||
pro,
|
||||
proTagBg
|
||||
}) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
export const FeatureBlock = ({ vertical, highlight, content, icon, pro, proTagBg }) => {
|
||||
const [state] = useTracked();
|
||||
const { colors } = state;
|
||||
|
||||
return vertical ? (
|
||||
<View
|
||||
@@ -25,8 +16,9 @@ export const FeatureBlock = ({
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 12,
|
||||
marginBottom: 10,
|
||||
}}>
|
||||
marginBottom: 10
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.accent} name="check" size={SIZE.lg} />
|
||||
|
||||
<Paragraph
|
||||
@@ -35,7 +27,8 @@ export const FeatureBlock = ({
|
||||
marginLeft: 5,
|
||||
flexShrink: 1
|
||||
}}
|
||||
size={SIZE.md}>
|
||||
size={SIZE.md}
|
||||
>
|
||||
{content}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -48,17 +41,18 @@ export const FeatureBlock = ({
|
||||
marginRight: 10,
|
||||
borderRadius: 5,
|
||||
minWidth: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.icon} name={icon} size={SIZE.xl} />
|
||||
<Paragraph size={SIZE.md}>
|
||||
<Text style={{color: colors.accent}}>{highlight}</Text>
|
||||
<Text style={{ color: colors.accent }}>{highlight}</Text>
|
||||
{'\n'}
|
||||
{content}
|
||||
</Paragraph>
|
||||
|
||||
{pro ? (
|
||||
<>
|
||||
<View style={{height: 5}} />
|
||||
<View style={{ height: 5 }} />
|
||||
<ProTag width={50} size={SIZE.xs} background={proTagBg} />
|
||||
</>
|
||||
) : (
|
||||
|
||||
@@ -39,8 +39,7 @@ export const features = [
|
||||
},
|
||||
{
|
||||
title: 'Attach files & images',
|
||||
detail:
|
||||
'Add your documents, PDFs, images and videos, and keep them safe and organized.',
|
||||
detail: 'Add your documents, PDFs, images and videos, and keep them safe and organized.',
|
||||
pro: true,
|
||||
features: [
|
||||
{
|
||||
@@ -78,8 +77,7 @@ export const features = [
|
||||
},
|
||||
{
|
||||
title: 'Organize yourself in the best way',
|
||||
detail:
|
||||
'We offer multiple ways to keep you organized. The only limit is your imagination.',
|
||||
detail: 'We offer multiple ways to keep you organized. The only limit is your imagination.',
|
||||
features: [
|
||||
{
|
||||
highlight: 'Unlimited',
|
||||
@@ -208,8 +206,7 @@ export const features = [
|
||||
},
|
||||
{
|
||||
title: 'Personalize & make Notesnook your own',
|
||||
detail:
|
||||
'Change app themes to match your style. Custom themes are coming soon.',
|
||||
detail: 'Change app themes to match your style. Custom themes are coming soon.',
|
||||
pro: true,
|
||||
features: [
|
||||
{
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {FeatureBlock} from './feature';
|
||||
import {ProTag} from './pro-tag';
|
||||
import { FeatureBlock } from './feature';
|
||||
import { ProTag } from './pro-tag';
|
||||
|
||||
export const Group = ({item, index}) => {
|
||||
export const Group = ({ item, index }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -15,15 +15,12 @@ export const Group = ({item, index}) => {
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 8,
|
||||
backgroundColor: index % 2 !== 0 ? colors.bg : colors.nav,
|
||||
paddingVertical: 40
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item?.pro ? (
|
||||
<ProTag
|
||||
size={SIZE.sm}
|
||||
background={index % 2 === 0 ? colors.bg : colors.nav}
|
||||
/>
|
||||
<ProTag size={SIZE.sm} background={index % 2 === 0 ? colors.bg : colors.nav} />
|
||||
) : null}
|
||||
<Heading>{item.title}</Heading>
|
||||
<Paragraph size={SIZE.md}>{item.detail}</Paragraph>
|
||||
@@ -34,9 +31,11 @@ export const Group = ({item, index}) => {
|
||||
marginTop: 20
|
||||
}}
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}>
|
||||
showsHorizontalScrollIndicator={false}
|
||||
>
|
||||
{item.features?.map(item => (
|
||||
<FeatureBlock
|
||||
key={item.detail}
|
||||
{...item}
|
||||
detail={item.detail}
|
||||
pro={item.pro}
|
||||
@@ -51,7 +50,8 @@ export const Group = ({item, index}) => {
|
||||
marginTop: 10
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
color={colors.icon}>
|
||||
color={colors.icon}
|
||||
>
|
||||
{item.info}
|
||||
</Paragraph>
|
||||
) : null}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, {createRef} from 'react';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import {eClosePremiumDialog, eOpenPremiumDialog} from '../../utils/Events';
|
||||
import React, { createRef } from 'react';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { eClosePremiumDialog, eOpenPremiumDialog } from '../../utils/Events';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import {Component} from './component';
|
||||
import { Component } from './component';
|
||||
|
||||
class PremiumDialog extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -46,15 +46,8 @@ class PremiumDialog extends React.Component {
|
||||
|
||||
render() {
|
||||
return !this.state.visible ? null : (
|
||||
<BaseDialog
|
||||
bounce
|
||||
background={this.props.colors.bg}
|
||||
onRequestClose={this.onClose}>
|
||||
<Component
|
||||
getRef={() => this.actionSheetRef}
|
||||
promo={this.state.promo}
|
||||
close={this.close}
|
||||
/>
|
||||
<BaseDialog bounce background={this.props.colors.bg} onRequestClose={this.onClose}>
|
||||
<Component getRef={() => this.actionSheetRef} promo={this.state.promo} close={this.close} />
|
||||
</BaseDialog>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
import React from 'react';
|
||||
import {Text} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { Text } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Offer = ({
|
||||
off = '30',
|
||||
text = 'on yearly plan, offer ends soon',
|
||||
padding = 0
|
||||
}) => {
|
||||
export const Offer = ({ off = '30', text = 'on yearly plan, offer ends soon', padding = 0 }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return (
|
||||
<Paragraph
|
||||
@@ -18,9 +14,10 @@ export const Offer = ({
|
||||
textAlign: 'center',
|
||||
paddingVertical: padding
|
||||
}}
|
||||
size={SIZE.xxxl}>
|
||||
size={SIZE.xxxl}
|
||||
>
|
||||
GET {off}
|
||||
<Text style={{color: colors.accent}}>%</Text> OFF!{'\n'}
|
||||
<Text style={{ color: colors.accent }}>%</Text> OFF!{'\n'}
|
||||
<Paragraph color={colors.icon}>{text}</Paragraph>
|
||||
</Paragraph>
|
||||
);
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import Animated, {Easing} from 'react-native-reanimated';
|
||||
import {useTracked} from '../../provider';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent
|
||||
} from '../../services/EventManager';
|
||||
import {dWidth, editing, getElevation} from '../../utils';
|
||||
import {
|
||||
eCloseActionSheet,
|
||||
eOpenPremiumDialog,
|
||||
eShowGetPremium
|
||||
} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import {EditorWebView} from '../../views/Editor/Functions';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import Animated, { Easing } from 'react-native-reanimated';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent, eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { dWidth, editing, getElevation } from '../../utils';
|
||||
import { eCloseActionSheet, eOpenPremiumDialog, eShowGetPremium } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { EditorWebView } from '../../views/Editor/Functions';
|
||||
import tiny from '../../views/Editor/tiny/tiny';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
@@ -29,9 +21,9 @@ let currentMsg = {
|
||||
title: '',
|
||||
desc: ''
|
||||
};
|
||||
export const PremiumToast = ({close, context = 'global', offset = 0}) => {
|
||||
export const PremiumToast = ({ close, context = 'global', offset = 0 }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [msg, setMsg] = useState(currentMsg);
|
||||
|
||||
const open = event => {
|
||||
@@ -130,19 +122,22 @@ export const PremiumToast = ({close, context = 'global', offset = 0}) => {
|
||||
translateY: translatePrem
|
||||
}
|
||||
]
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexShrink: 1,
|
||||
flexGrow: 1,
|
||||
paddingRight: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
color={colors.accent}
|
||||
size={SIZE.md}>
|
||||
size={SIZE.md}
|
||||
>
|
||||
{msg.title}
|
||||
</Heading>
|
||||
|
||||
@@ -151,7 +146,8 @@ export const PremiumToast = ({close, context = 'global', offset = 0}) => {
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
size={SIZE.sm}
|
||||
color={colors.pri}>
|
||||
color={colors.pri}
|
||||
>
|
||||
{msg.desc}
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { getElevation } from '../../utils';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const PricingItem = ({product, onPress, compact}) => {
|
||||
export const PricingItem = ({ product, onPress, compact }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -22,27 +22,22 @@ export const PricingItem = ({product, onPress, compact}) => {
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: compact ? 15 : 10,
|
||||
width: compact ? null : '100%',
|
||||
minWidth: 150,
|
||||
}}>
|
||||
minWidth: 150
|
||||
}}
|
||||
>
|
||||
{!compact && (
|
||||
<View>
|
||||
<Heading size={SIZE.lg - 2}>
|
||||
{product?.type === 'yearly' || product?.offerType === 'yearly'
|
||||
? 'Yearly'
|
||||
: 'Monthly'}
|
||||
{product?.type === 'yearly' || product?.offerType === 'yearly' ? 'Yearly' : 'Monthly'}
|
||||
</Heading>
|
||||
{product?.info && (
|
||||
<Paragraph size={SIZE.xs}>{product.info}</Paragraph>
|
||||
)}
|
||||
{product?.info && <Paragraph size={SIZE.xs}>{product.info}</Paragraph>}
|
||||
</View>
|
||||
)}
|
||||
|
||||
<View>
|
||||
<Paragraph size={SIZE.sm}>
|
||||
<Heading size={SIZE.lg - 2}>{product?.data?.localizedPrice}/</Heading>
|
||||
{product?.type === 'yearly' || product?.offerType === 'yearly'
|
||||
? '/year'
|
||||
: '/month'}
|
||||
{product?.type === 'yearly' || product?.offerType === 'yearly' ? '/year' : '/month'}
|
||||
</Paragraph>
|
||||
</View>
|
||||
</PressableButton>
|
||||
|
||||
@@ -1,32 +1,28 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {ActivityIndicator, Platform, Text, View} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ActivityIndicator, Platform, Text, View } from 'react-native';
|
||||
import * as RNIap from 'react-native-iap';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useUserStore} from '../../provider/stores';
|
||||
import {
|
||||
eSendEvent,
|
||||
presentSheet,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useUserStore } from '../../provider/stores';
|
||||
import { eSendEvent, presentSheet, ToastEvent } from '../../services/EventManager';
|
||||
import PremiumService from '../../services/PremiumService';
|
||||
import {db} from '../../utils/database';
|
||||
import { db } from '../../utils/database';
|
||||
import {
|
||||
eClosePremiumDialog,
|
||||
eCloseProgressDialog,
|
||||
eCloseSimpleDialog,
|
||||
eOpenLoginDialog
|
||||
} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import umami from '../../utils/umami';
|
||||
import {Button} from '../Button';
|
||||
import {Dialog} from '../Dialog';
|
||||
import { Button } from '../Button';
|
||||
import { Dialog } from '../Dialog';
|
||||
import BaseDialog from '../Dialog/base-dialog';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {PricingItem} from './pricing-item';
|
||||
import { PricingItem } from './pricing-item';
|
||||
|
||||
const promoCyclesMonthly = {
|
||||
1: 'first month',
|
||||
@@ -40,12 +36,7 @@ const promoCyclesYearly = {
|
||||
3: 'first 3 years'
|
||||
};
|
||||
|
||||
export const PricingPlans = ({
|
||||
promo,
|
||||
marginTop,
|
||||
heading = true,
|
||||
compact = false
|
||||
}) => {
|
||||
export const PricingPlans = ({ promo, marginTop, heading = true, compact = false }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const colors = state.colors;
|
||||
const user = useUserStore(state => state.user);
|
||||
@@ -61,12 +52,8 @@ export const PricingPlans = ({
|
||||
let products = await PremiumService.getProducts();
|
||||
if (products.length > 0) {
|
||||
let offers = {
|
||||
monthly: products.find(
|
||||
p => p.productId === 'com.streetwriters.notesnook.sub.mo'
|
||||
),
|
||||
yearly: products.find(
|
||||
p => p.productId === 'com.streetwriters.notesnook.sub.yr'
|
||||
)
|
||||
monthly: products.find(p => p.productId === 'com.streetwriters.notesnook.sub.mo'),
|
||||
yearly: products.find(p => p.productId === 'com.streetwriters.notesnook.sub.yr')
|
||||
};
|
||||
setOffers(offers);
|
||||
|
||||
@@ -98,12 +85,10 @@ export const PricingPlans = ({
|
||||
let isMonthly = product.productId.indexOf('.mo') > -1;
|
||||
let cycleText = isMonthly
|
||||
? promoCyclesMonthly[
|
||||
product.introductoryPriceCyclesAndroid ||
|
||||
product.introductoryPriceNumberOfPeriodsIOS
|
||||
product.introductoryPriceCyclesAndroid || product.introductoryPriceNumberOfPeriodsIOS
|
||||
]
|
||||
: promoCyclesYearly[
|
||||
product.introductoryPriceCyclesAndroid ||
|
||||
product.introductoryPriceNumberOfPeriodsIOS
|
||||
product.introductoryPriceCyclesAndroid || product.introductoryPriceNumberOfPeriodsIOS
|
||||
];
|
||||
|
||||
setProduct({
|
||||
@@ -132,18 +117,8 @@ export const PricingPlans = ({
|
||||
setBuying(false);
|
||||
return;
|
||||
}
|
||||
umami.pageView(
|
||||
'/iap-native',
|
||||
`${compact ? 'pro-sheet' : 'pro-screen'}/pro-plans`
|
||||
);
|
||||
await RNIap.requestSubscription(
|
||||
product?.productId,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
user.id
|
||||
);
|
||||
umami.pageView('/iap-native', `${compact ? 'pro-sheet' : 'pro-screen'}/pro-plans`);
|
||||
await RNIap.requestSubscription(product?.productId, false, null, null, null, user.id);
|
||||
setBuying(false);
|
||||
eSendEvent(eCloseProgressDialog);
|
||||
eSendEvent(eClosePremiumDialog);
|
||||
@@ -170,14 +145,16 @@ export const PricingPlans = ({
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator color={colors.accent} size={25} />
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{buying ? (
|
||||
<BaseDialog statusBarTranslucent centered>
|
||||
<ActivityIndicator size={50} color="white" />
|
||||
@@ -190,14 +167,16 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
textAlign: 'center'
|
||||
}}
|
||||
size={SIZE.lg - 4}>
|
||||
size={SIZE.lg - 4}
|
||||
>
|
||||
{product.data.introductoryPrice}
|
||||
<Paragraph
|
||||
style={{
|
||||
textDecorationLine: 'line-through',
|
||||
color: colors.icon
|
||||
}}
|
||||
size={SIZE.sm}>
|
||||
size={SIZE.sm}
|
||||
>
|
||||
({product.data.localizedPrice})
|
||||
</Paragraph>{' '}
|
||||
for {product.cycleText}
|
||||
@@ -212,7 +191,8 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
marginTop: marginTop || 20,
|
||||
marginBottom: 20
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Choose a plan
|
||||
</Heading>
|
||||
) : null}
|
||||
@@ -222,7 +202,8 @@ export const PricingPlans = ({
|
||||
flexDirection: !compact ? 'column' : 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-around'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<PricingItem
|
||||
onPress={() => buySubscription(offers?.monthly)}
|
||||
compact={compact}
|
||||
@@ -271,8 +252,7 @@ export const PricingPlans = ({
|
||||
eSendEvent(eCloseSimpleDialog);
|
||||
setBuying(true);
|
||||
try {
|
||||
if (!(await getPromo(value)))
|
||||
throw new Error('Error applying promo code');
|
||||
if (!(await getPromo(value))) throw new Error('Error applying promo code');
|
||||
ToastEvent.show({
|
||||
heading: 'Discount applied!',
|
||||
type: 'success',
|
||||
@@ -333,12 +313,14 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Use promo code{' '}
|
||||
<Text
|
||||
style={{
|
||||
fontFamily: 'OpenSans-SemiBold'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{promo.promoCode}
|
||||
</Text>{' '}
|
||||
at checkout
|
||||
@@ -380,14 +362,13 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
textAlign: 'center',
|
||||
marginTop: 10
|
||||
}}>
|
||||
Upon signing up, your 14 day free trial of Notesnook Pro will be
|
||||
activated automatically.{' '}
|
||||
<Paragraph size={SIZE.xs} style={{fontWeight: 'bold'}}>
|
||||
}}
|
||||
>
|
||||
Upon signing up, your 14 day free trial of Notesnook Pro will be activated automatically.{' '}
|
||||
<Paragraph size={SIZE.xs} style={{ fontWeight: 'bold' }}>
|
||||
No credit card information is required.
|
||||
</Paragraph>{' '}
|
||||
Once the free trial period ends, your account will be downgraded to
|
||||
basic free account.{' '}
|
||||
Once the free trial period ends, your account will be downgraded to basic free account.{' '}
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
onPress={() => {
|
||||
@@ -398,9 +379,9 @@ export const PricingPlans = ({
|
||||
});
|
||||
}}
|
||||
color={colors.accent}
|
||||
style={{fontWeight: 'bold', textDecorationLine: 'underline'}}>
|
||||
Visit our website to learn what is included in the basic free
|
||||
account.
|
||||
style={{ fontWeight: 'bold', textDecorationLine: 'underline' }}
|
||||
>
|
||||
Visit our website to learn what is included in the basic free account.
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
) : null}
|
||||
@@ -416,10 +397,11 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
marginTop: 10,
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
By subscribing, you will be charged to your iTunes Account for the
|
||||
selected plan. Subscriptions will automatically renew unless
|
||||
cancelled within 24-hours before the end of the current period.
|
||||
}}
|
||||
>
|
||||
By subscribing, you will be charged to your iTunes Account for the selected plan.
|
||||
Subscriptions will automatically renew unless cancelled within 24-hours before the end
|
||||
of the current period.
|
||||
</Paragraph>
|
||||
) : (
|
||||
<Paragraph
|
||||
@@ -429,24 +411,26 @@ export const PricingPlans = ({
|
||||
alignSelf: 'center',
|
||||
marginTop: 10,
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
By subscribing, your will be charged on your Google Account, and
|
||||
your subscription will automatically renew until you cancel prior
|
||||
to the end of the then current period.
|
||||
}}
|
||||
>
|
||||
By subscribing, your will be charged on your Google Account, and your subscription
|
||||
will automatically renew until you cancel prior to the end of the then current period.
|
||||
</Paragraph>
|
||||
)}
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
color={colors.icon}
|
||||
style={{
|
||||
maxWidth: '100%',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
By subscribing, you agree to our{' '}
|
||||
<Paragraph
|
||||
size={SIZE.xs}
|
||||
@@ -460,7 +444,8 @@ export const PricingPlans = ({
|
||||
style={{
|
||||
textDecorationLine: 'underline'
|
||||
}}
|
||||
color={colors.accent}>
|
||||
color={colors.accent}
|
||||
>
|
||||
Terms of Service{' '}
|
||||
</Paragraph>
|
||||
and{' '}
|
||||
@@ -476,7 +461,8 @@ export const PricingPlans = ({
|
||||
style={{
|
||||
textDecorationLine: 'underline'
|
||||
}}
|
||||
color={colors.accent}>
|
||||
color={colors.accent}
|
||||
>
|
||||
Privacy Policy.
|
||||
</Paragraph>
|
||||
</Paragraph>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import { useTracked } from '../../provider';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const ProTag = ({width, size, background}) => {
|
||||
export const ProTag = ({ width, size, background }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
|
||||
@@ -13,12 +13,13 @@ export const ProTag = ({width, size, background}) => {
|
||||
style={{
|
||||
backgroundColor: background || colors.bg,
|
||||
borderRadius: 100,
|
||||
width:width || 60,
|
||||
width: width || 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 2.5,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
style={{
|
||||
marginRight: 3
|
||||
|
||||
@@ -32,25 +32,31 @@ export const PressableButton = ({
|
||||
customOpacity
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
|
||||
const selectedColor = customSelectedColor ||
|
||||
const { colors } = state;
|
||||
|
||||
const selectedColor =
|
||||
customSelectedColor ||
|
||||
colors[
|
||||
type === 'accent'
|
||||
? BUTTON_TYPES[type](accentColor, accentText).selected
|
||||
: BUTTON_TYPES[type].selected
|
||||
];
|
||||
const primaryColor = customColor ||
|
||||
const primaryColor =
|
||||
customColor ||
|
||||
colors[
|
||||
type === 'accent'
|
||||
? BUTTON_TYPES[type](accentColor, accentText).primary
|
||||
: BUTTON_TYPES[type].primary
|
||||
];
|
||||
const opacity = customOpacity ? customOpacity : type === 'accent' ? 1 : BUTTON_TYPES[type].opacity;
|
||||
const alpha = customAlpha? customAlpha : colors.night ? 0.04 : -0.04;
|
||||
const opacity = customOpacity
|
||||
? customOpacity
|
||||
: type === 'accent'
|
||||
? 1
|
||||
: BUTTON_TYPES[type].opacity;
|
||||
const alpha = customAlpha ? customAlpha : colors.night ? 0.04 : -0.04;
|
||||
|
||||
const getStyle = useCallback(
|
||||
({pressed}) => [
|
||||
({ pressed }) => [
|
||||
{
|
||||
backgroundColor: pressed
|
||||
? RGB_Linear_Shade(alpha, hexToRGBA(selectedColor, opacity || 1))
|
||||
@@ -60,11 +66,11 @@ export const PressableButton = ({
|
||||
borderRadius: noborder ? 0 : br,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginBottom: 0,
|
||||
marginBottom: 0
|
||||
},
|
||||
customStyle,
|
||||
customStyle
|
||||
],
|
||||
[customStyle, noborder, type,colors],
|
||||
[customStyle, noborder, type, colors]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -74,7 +80,8 @@ export const PressableButton = ({
|
||||
hitSlop={hitSlop}
|
||||
onPress={onPress}
|
||||
onLongPress={onLongPress}
|
||||
style={getStyle}>
|
||||
style={getStyle}
|
||||
>
|
||||
{children}
|
||||
</Pressable>
|
||||
);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import React, {useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import React, { useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useMenuStore, useSettingStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useMenuStore, useSettingStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {dWidth} from '../../utils';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {db} from '../../utils/database';
|
||||
import {refreshNotesPage} from '../../utils/Events';
|
||||
import { dWidth } from '../../utils';
|
||||
import { COLORS_NOTE } from '../../utils/Colors';
|
||||
import { db } from '../../utils/database';
|
||||
import { refreshNotesPage } from '../../utils/Events';
|
||||
import layoutmanager from '../../utils/layout-manager';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
|
||||
export const ColorTags = ({item, close}) => {
|
||||
export const ColorTags = ({ item, close }) => {
|
||||
const [note, setNote] = useState(item);
|
||||
const setColorNotes = useMenuStore(state => state.setColorNotes);
|
||||
const dimensions = useSettingStore(state => state.dimensions);
|
||||
@@ -27,7 +27,7 @@ export const ColorTags = ({item, close}) => {
|
||||
await db.notes.note(note.id).color(color.name);
|
||||
}
|
||||
let _note = db.notes.note(note.id).data;
|
||||
setNote({..._note});
|
||||
setNote({ ..._note });
|
||||
setColorNotes();
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.NotesPage,
|
||||
@@ -56,7 +56,8 @@ export const ColorTags = ({item, close}) => {
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{note.color?.toLowerCase() === color.name ? (
|
||||
<Icon name="check" color="white" size={SIZE.lg} />
|
||||
) : null}
|
||||
@@ -75,7 +76,8 @@ export const ColorTags = ({item, close}) => {
|
||||
marginTop: 20,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{Object.keys(COLORS_NOTE).map(_renderColor)}
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { timeConverter } from '../../utils/TimeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const DateMeta = ({item}) => {
|
||||
export const DateMeta = ({ item }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const getNameFromKey = key => {
|
||||
switch (key) {
|
||||
@@ -30,7 +30,8 @@ export const DateMeta = ({item}) => {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
paddingVertical: 3
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.xs} color={colors.icon}>
|
||||
{getNameFromKey(key)}
|
||||
</Paragraph>
|
||||
@@ -48,7 +49,8 @@ export const DateMeta = ({item}) => {
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.nav,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{Object.keys(item).map(renderItem)}
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { db } from '../../utils/database';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const DevMode = ({item}) => {
|
||||
export const DevMode = ({ item }) => {
|
||||
const settings = useSettingStore(state => state.settings);
|
||||
|
||||
return settings.devMode ? (
|
||||
@@ -16,7 +16,8 @@ export const DevMode = ({item}) => {
|
||||
width: '100%',
|
||||
paddingHorizontal: 12,
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onPress={async () => {
|
||||
let additionalData = {};
|
||||
@@ -28,7 +29,7 @@ export const DevMode = ({item}) => {
|
||||
}
|
||||
}
|
||||
additionalData.lastSynced = await db.lastSynced();
|
||||
let _note = {...item};
|
||||
let _note = { ...item };
|
||||
_note.additionalData = additionalData;
|
||||
Clipboard.setString(db.debug.strip(_note));
|
||||
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import React from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {presentSheet} from '../../services/EventManager';
|
||||
import {db} from '../../utils/database';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { Platform, ScrollView, View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { presentSheet } from '../../services/EventManager';
|
||||
import { db } from '../../utils/database';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {ColorTags} from './color-tags';
|
||||
import {DateMeta} from './date-meta';
|
||||
import {DevMode} from './dev-mode';
|
||||
import {Items} from './items';
|
||||
import { ColorTags } from './color-tags';
|
||||
import { DateMeta } from './date-meta';
|
||||
import { DevMode } from './dev-mode';
|
||||
import { Items } from './items';
|
||||
import Notebooks from './notebooks';
|
||||
import {Synced} from './synced';
|
||||
import {Tags} from './tags';
|
||||
import {Topics} from './topics';
|
||||
import { Synced } from './synced';
|
||||
import { Tags } from './tags';
|
||||
import { Topics } from './topics';
|
||||
|
||||
export const Properties = ({close = () => {}, item, buttons = [], getRef}) => {
|
||||
export const Properties = ({ close = () => {}, item, buttons = [], getRef }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const alias = item
|
||||
? item.type === 'tag'
|
||||
@@ -43,9 +43,10 @@ export const Properties = ({close = () => {}, item, buttons = [], getRef}) => {
|
||||
paddingHorizontal: 0,
|
||||
borderBottomRightRadius: DDS.isLargeTablet() ? 10 : 1,
|
||||
borderBottomLeftRadius: DDS.isLargeTablet() ? 10 : 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{!item || !item.id ? (
|
||||
<Paragraph style={{marginVertical: 10, alignSelf: 'center'}}>
|
||||
<Paragraph style={{ marginVertical: 10, alignSelf: 'center' }}>
|
||||
Start writing to save your note.
|
||||
</Paragraph>
|
||||
) : (
|
||||
@@ -53,11 +54,13 @@ export const Properties = ({close = () => {}, item, buttons = [], getRef}) => {
|
||||
style={{
|
||||
marginTop: 5,
|
||||
zIndex: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.lg}>
|
||||
{item.type === 'tag' ? '#' : null}
|
||||
{alias}
|
||||
@@ -65,12 +68,10 @@ export const Properties = ({close = () => {}, item, buttons = [], getRef}) => {
|
||||
|
||||
{item.headline || item.description ? (
|
||||
<Paragraph numberOfLines={2} color={colors.icon}>
|
||||
{(item.type === 'notebook' || item.itemType === 'notebook') &&
|
||||
item?.description
|
||||
{(item.type === 'notebook' || item.itemType === 'notebook') && item?.description
|
||||
? item.description
|
||||
: null}
|
||||
{(item.type === 'note' || item.itemType === 'note') &&
|
||||
item?.headline
|
||||
{(item.type === 'note' || item.itemType === 'note') && item?.headline
|
||||
? item.headline
|
||||
: null}
|
||||
</Paragraph>
|
||||
@@ -81,9 +82,7 @@ export const Properties = ({close = () => {}, item, buttons = [], getRef}) => {
|
||||
<Topics item={item} close={close} />
|
||||
</View>
|
||||
|
||||
{item.type === 'note' ? (
|
||||
<Notebooks note={item} close={close} />
|
||||
) : null}
|
||||
{item.type === 'note' ? <Notebooks note={item} close={close} /> : null}
|
||||
|
||||
<DateMeta item={item} />
|
||||
</View>
|
||||
@@ -117,13 +116,13 @@ Properties.present = (item, buttons = []) => {
|
||||
if (!item) return;
|
||||
let type = item?.type;
|
||||
let props = [item];
|
||||
|
||||
let android = [];
|
||||
switch (type) {
|
||||
case 'trash':
|
||||
props.push(['PermDelete', 'Restore']);
|
||||
break;
|
||||
case 'note':
|
||||
let android = Platform.OS === 'android' ? ['PinToNotif'] : [];
|
||||
android = Platform.OS === 'android' ? ['PinToNotif'] : [];
|
||||
props.push([
|
||||
'Add to notebook',
|
||||
'Share',
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {FlatList} from 'react-native-gesture-handler';
|
||||
import { View } from 'react-native';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useSettingStore} from '../../provider/stores';
|
||||
import {DDS} from '../../services/DeviceDetection';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSettingStore } from '../../provider/stores';
|
||||
import { DDS } from '../../services/DeviceDetection';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {useActions} from './use-actions';
|
||||
import { useActions } from './use-actions';
|
||||
|
||||
export const Items = ({item, buttons, close}) => {
|
||||
export const Items = ({ item, buttons, close }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const dimensions = useSettingStore(state => state.dimensions);
|
||||
const actions = useActions({item, close});
|
||||
const actions = useActions({ item, close });
|
||||
const data = actions.filter(i => buttons.indexOf(i.name) > -1 && !i.hidden);
|
||||
|
||||
let width = dimensions.width > 600 ? 600 : dimensions.width;
|
||||
@@ -24,7 +24,7 @@ export const Items = ({item, buttons, close}) => {
|
||||
? (width - 24) / columnItemsCount
|
||||
: (width - 24) / columnItemsCount;
|
||||
|
||||
const _renderRowItem = ({item, index}) => (
|
||||
const _renderRowItem = ({ item, index }) => (
|
||||
<View
|
||||
onPress={item.func}
|
||||
key={item.name}
|
||||
@@ -33,7 +33,8 @@ export const Items = ({item, buttons, close}) => {
|
||||
alignItems: 'center',
|
||||
width: columnItemWidth,
|
||||
marginBottom: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<PressableButton
|
||||
onPress={item.func}
|
||||
type={item.on ? 'shade' : 'grayBg'}
|
||||
@@ -46,7 +47,8 @@ export const Items = ({item, buttons, close}) => {
|
||||
textAlign: 'center',
|
||||
textAlignVertical: 'center',
|
||||
marginBottom: DDS.isTab ? 7 : 3.5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name={item.icon}
|
||||
size={DDS.isTab ? SIZE.xxl : SIZE.lg}
|
||||
@@ -60,13 +62,13 @@ export const Items = ({item, buttons, close}) => {
|
||||
/>
|
||||
</PressableButton>
|
||||
|
||||
<Paragraph size={SIZE.xs + 1} style={{textAlign: 'center'}}>
|
||||
<Paragraph size={SIZE.xs + 1} style={{ textAlign: 'center' }}>
|
||||
{item.title}
|
||||
</Paragraph>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderColumnItem = ({item, index}) => (
|
||||
const renderColumnItem = ({ item, index }) => (
|
||||
<Button
|
||||
buttonType={{
|
||||
text: item.on
|
||||
@@ -109,10 +111,6 @@ export const Items = ({item, buttons, close}) => {
|
||||
renderItem={_renderRowItem}
|
||||
/>
|
||||
) : (
|
||||
<FlatList
|
||||
data={data}
|
||||
keyExtractor={item => item.title}
|
||||
renderItem={renderColumnItem}
|
||||
/>
|
||||
<FlatList data={data} keyExtractor={item => item.title} renderItem={renderColumnItem} />
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React from 'react';
|
||||
import {ScrollView, View} from 'react-native';
|
||||
import { ScrollView, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOnNewTopicAdded, refreshNotesPage} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOnNewTopicAdded, refreshNotesPage } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Heading from '../Typography/Heading';
|
||||
|
||||
export default function Notebooks({note, close}) {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
export default function Notebooks({ note, close }) {
|
||||
const [state] = useTracked();
|
||||
const { colors } = state;
|
||||
|
||||
function getNotebooks(item) {
|
||||
if (!item.notebooks || item.notebooks.length < 1) return [];
|
||||
@@ -63,7 +63,7 @@ export default function Notebooks({note, close}) {
|
||||
let routeName = 'NotesPage';
|
||||
let item = db.notebooks.notebook(notebookId).topics.topic(id)._topic;
|
||||
|
||||
let params = {...item, menu: false};
|
||||
let params = { ...item, menu: false };
|
||||
let headerState = {
|
||||
heading: item.title,
|
||||
id: item.id,
|
||||
@@ -79,9 +79,11 @@ export default function Notebooks({note, close}) {
|
||||
width: '100%',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{getNotebooks(note).map(item => (
|
||||
<PressableButton
|
||||
key={item.id}
|
||||
onPress={() => {
|
||||
navigateNotebook(item.id);
|
||||
close();
|
||||
@@ -95,7 +97,8 @@ export default function Notebooks({note, close}) {
|
||||
flexGrow: 1,
|
||||
marginTop: 5,
|
||||
paddingVertical: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="book-outline"
|
||||
color={colors.accent}
|
||||
@@ -109,7 +112,8 @@ export default function Notebooks({note, close}) {
|
||||
style={{
|
||||
maxWidth: '50%'
|
||||
}}
|
||||
size={SIZE.sm}>
|
||||
size={SIZE.sm}
|
||||
>
|
||||
{item.title}
|
||||
</Heading>
|
||||
|
||||
@@ -122,9 +126,11 @@ export default function Notebooks({note, close}) {
|
||||
borderLeftColor: colors.nav,
|
||||
borderLeftWidth: 1,
|
||||
paddingLeft: 8
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.topics.map(topic => (
|
||||
<Button
|
||||
key={topic.id}
|
||||
onPress={() => {
|
||||
navigateTopic(topic.id, item.id);
|
||||
close();
|
||||
@@ -141,7 +147,7 @@ export default function Notebooks({note, close}) {
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<View style={{width: 10}} />
|
||||
<View style={{ width: 10 }} />
|
||||
</ScrollView>
|
||||
</PressableButton>
|
||||
))}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useUserStore} from '../../provider/stores';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useUserStore } from '../../provider/stores';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { Button } from '../Button';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Synced = ({item, close}) => {
|
||||
export const Synced = ({ item, close }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const user = useUserStore(state => state.user);
|
||||
const lastSynced = useUserStore(state => state.lastSynced);
|
||||
|
||||
@@ -30,7 +30,8 @@ export const Synced = ({item, close}) => {
|
||||
marginTop: 10,
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon name="shield-key-outline" color={colors.accent} size={SIZE.xxxl} />
|
||||
|
||||
<View
|
||||
@@ -38,13 +39,15 @@ export const Synced = ({item, close}) => {
|
||||
flex: 1,
|
||||
marginLeft: 5,
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
color={colors.heading}
|
||||
size={SIZE.xs}
|
||||
style={{
|
||||
flexWrap: 'wrap'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Encrypted and synced
|
||||
</Heading>
|
||||
<Paragraph
|
||||
@@ -52,7 +55,8 @@ export const Synced = ({item, close}) => {
|
||||
flexWrap: 'wrap'
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
color={colors.pri}>
|
||||
color={colors.pri}
|
||||
>
|
||||
No one can view this {item.itemType || item.type} except you.
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -62,10 +66,7 @@ export const Synced = ({item, close}) => {
|
||||
try {
|
||||
close();
|
||||
await sleep(300);
|
||||
await openLinkInBrowser(
|
||||
'https://docs.notesnook.com/how-is-my-data-encrypted/',
|
||||
colors
|
||||
);
|
||||
await openLinkInBrowser('https://docs.notesnook.com/how-is-my-data-encrypted/', colors);
|
||||
} catch (e) {}
|
||||
}}
|
||||
fontSize={SIZE.xs + 1}
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
import React, {useState} from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import React, { useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOpenTagsDialog, refreshNotesPage} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenTagsDialog, refreshNotesPage } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const Tags = ({item, close}) => {
|
||||
export const Tags = ({ item, close }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return item.id ? (
|
||||
<View
|
||||
style={{
|
||||
marginTop: 5,
|
||||
marginBottom: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onPress={async () => {
|
||||
close();
|
||||
@@ -41,8 +43,7 @@ export const Tags = ({item, close}) => {
|
||||
height={25}
|
||||
fontSize={SIZE.xs + 1}
|
||||
style={{
|
||||
marginRight:5,
|
||||
paddingHorizontal: 0,
|
||||
marginRight: 5,
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 8
|
||||
}}
|
||||
@@ -55,7 +56,7 @@ export const Tags = ({item, close}) => {
|
||||
) : null;
|
||||
};
|
||||
|
||||
const TagItem = ({tag, close}) => {
|
||||
const TagItem = ({ tag, close }) => {
|
||||
const onPress = async () => {
|
||||
let tags = db.tags.all;
|
||||
let _tag = tags.find(t => t.title === tag);
|
||||
@@ -76,7 +77,6 @@ const TagItem = ({tag, close}) => {
|
||||
};
|
||||
|
||||
const style = {
|
||||
paddingHorizontal: 0,
|
||||
paddingHorizontal: 8,
|
||||
marginVertical: 5,
|
||||
borderRadius: 100,
|
||||
|
||||
@@ -1,21 +1,17 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import { View } from 'react-native';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {refreshNotesPage} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import { refreshNotesPage } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
|
||||
export const Topics = ({item, close}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
|
||||
const open = (topic) => {
|
||||
export const Topics = ({ item, close }) => {
|
||||
const open = topic => {
|
||||
close();
|
||||
|
||||
let routeName = 'NotesPage';
|
||||
let params = {...topic, menu: false, get: 'topics'};
|
||||
let params = { ...topic, menu: false, get: 'topics' };
|
||||
let headerState = {
|
||||
heading: topic.title,
|
||||
id: topic.id,
|
||||
@@ -39,7 +35,6 @@ export const Topics = ({item, close}) => {
|
||||
fontSize={SIZE.xs + 1}
|
||||
style={{
|
||||
marginRight: 5,
|
||||
paddingHorizontal: 0,
|
||||
paddingHorizontal: 8,
|
||||
borderRadius: 100,
|
||||
marginVertical: 5
|
||||
@@ -47,17 +42,15 @@ export const Topics = ({item, close}) => {
|
||||
/>
|
||||
);
|
||||
|
||||
return item &&
|
||||
item.type === 'notebook' &&
|
||||
item.topics &&
|
||||
item.topics.length > 0 ? (
|
||||
return item && item.type === 'notebook' && item.topics && item.topics.length > 0 ? (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
marginTop: 5,
|
||||
width: '100%',
|
||||
flexWrap: 'wrap'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{item.topics
|
||||
.sort((a, b) => a.dateEdited - b.dateEdited)
|
||||
.slice(0, 6)
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {Platform} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import Share from 'react-native-share';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {
|
||||
useMenuStore,
|
||||
useSelectionStore,
|
||||
useTagStore,
|
||||
useUserStore
|
||||
} from '../../provider/stores';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Actions } from '../../provider/Actions';
|
||||
import { useMenuStore, useSelectionStore, useTagStore, useUserStore } from '../../provider/stores';
|
||||
import {
|
||||
eSendEvent,
|
||||
eSubscribeEvent,
|
||||
@@ -22,7 +17,7 @@ import {
|
||||
import Navigation from '../../services/Navigation';
|
||||
import Notifications from '../../services/Notifications';
|
||||
import SettingsService from '../../services/SettingsService';
|
||||
import {editing, toTXT} from '../../utils';
|
||||
import { editing, toTXT } from '../../utils';
|
||||
import {
|
||||
ACCENT,
|
||||
COLOR_SCHEME,
|
||||
@@ -31,7 +26,7 @@ import {
|
||||
COLOR_SCHEME_PITCH_BLACK,
|
||||
setColorScheme
|
||||
} from '../../utils/Colors';
|
||||
import {db} from '../../utils/database';
|
||||
import { db } from '../../utils/database';
|
||||
import {
|
||||
eOpenAddNotebookDialog,
|
||||
eOpenAddTopicDialog,
|
||||
@@ -41,21 +36,19 @@ import {
|
||||
eOpenMoveNoteDialog,
|
||||
eOpenPublishNoteDialog
|
||||
} from '../../utils/Events';
|
||||
import {deleteItems} from '../../utils/functions';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import { deleteItems } from '../../utils/functions';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import NoteHistory from '../NoteHistory';
|
||||
|
||||
export const useActions = ({close = () => {}, item}) => {
|
||||
export const useActions = ({ close = () => {}, item }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const clearSelection = useSelectionStore(state => state.clearSelection);
|
||||
const setSelectedItem = useSelectionStore(state => state.setSelectedItem);
|
||||
const setMenuPins = useMenuStore(state => state.setMenuPins);
|
||||
const [isPinnedToMenu, setIsPinnedToMenu] = useState(
|
||||
db.settings.isPinned(item.id)
|
||||
);
|
||||
const [isPinnedToMenu, setIsPinnedToMenu] = useState(db.settings.isPinned(item.id));
|
||||
|
||||
const user = useUserStore(state => state.user);
|
||||
const [notifPinned, setNotifPinned] = useState(null);
|
||||
@@ -66,8 +59,7 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
? db.colors.alias(item.id)
|
||||
: item.title;
|
||||
|
||||
const isPublished =
|
||||
item.type === 'note' && db.monographs.isPublished(item.id);
|
||||
const isPublished = item.type === 'note' && db.monographs.isPublished(item.id);
|
||||
const noteInTopic =
|
||||
item.type === 'note' &&
|
||||
editing.actionAfterFirstSave.type === 'topic' &&
|
||||
@@ -117,19 +109,19 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
|
||||
function changeColorScheme(colors = COLOR_SCHEME, accent = ACCENT) {
|
||||
let newColors = setColorScheme(colors, accent);
|
||||
dispatch({type: Actions.THEME, colors: newColors});
|
||||
dispatch({ type: Actions.THEME, colors: newColors });
|
||||
}
|
||||
|
||||
function switchTheme() {
|
||||
if (!colors.night) {
|
||||
MMKV.setStringAsync('theme', JSON.stringify({night: true}));
|
||||
MMKV.setStringAsync('theme', JSON.stringify({ night: true }));
|
||||
let nextTheme = SettingsService.get().pitchBlack
|
||||
? COLOR_SCHEME_PITCH_BLACK
|
||||
: COLOR_SCHEME_DARK;
|
||||
changeColorScheme(nextTheme);
|
||||
return;
|
||||
}
|
||||
MMKV.setStringAsync('theme', JSON.stringify({night: false}));
|
||||
MMKV.setStringAsync('theme', JSON.stringify({ night: false }));
|
||||
changeColorScheme(COLOR_SCHEME_LIGHT);
|
||||
}
|
||||
|
||||
@@ -165,10 +157,7 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
return;
|
||||
}
|
||||
await db[`${type}s`][type](item.id).pin();
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.Notebooks,
|
||||
Navigation.routeNames.Notes
|
||||
]);
|
||||
Navigation.setRoutesToUpdate([Navigation.routeNames.Notebooks, Navigation.routeNames.Notes]);
|
||||
}
|
||||
|
||||
async function pinToNotifications() {
|
||||
@@ -206,12 +195,9 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
Navigation.routeNames.Favorites,
|
||||
Navigation.routeNames.Trash
|
||||
]);
|
||||
type = item.type === 'trash' ? item.itemType : item.type;
|
||||
let type = item.type === 'trash' ? item.itemType : item.type;
|
||||
ToastEvent.show({
|
||||
heading:
|
||||
type === 'note'
|
||||
? 'Note restored from trash'
|
||||
: 'Notebook restored from trash',
|
||||
heading: type === 'note' ? 'Note restored from trash' : 'Notebook restored from trash',
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
@@ -337,7 +323,7 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
notebookId: item.notebookId
|
||||
});
|
||||
} else {
|
||||
await db.settings.pin(item.type, {id: item.id});
|
||||
await db.settings.pin(item.type, { id: item.id });
|
||||
}
|
||||
}
|
||||
setIsPinnedToMenu(db.settings.isPinned(item.id));
|
||||
@@ -526,10 +512,7 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
},
|
||||
{
|
||||
name: 'PinToNotif',
|
||||
title:
|
||||
notifPinned !== null
|
||||
? 'Unpin from Notifications'
|
||||
: 'Pin to Notifications',
|
||||
title: notifPinned !== null ? 'Unpin from Notifications' : 'Pin to Notifications',
|
||||
icon: 'bell',
|
||||
on: notifPinned !== null,
|
||||
func: pinToNotifications
|
||||
@@ -631,9 +614,7 @@ export const useActions = ({close = () => {}, item}) => {
|
||||
{
|
||||
name: 'Delete',
|
||||
title:
|
||||
item.type !== 'notebook' && item.type !== 'note'
|
||||
? 'Delete ' + item.type
|
||||
: 'Move to trash',
|
||||
item.type !== 'notebook' && item.type !== 'note' ? 'Delete ' + item.type : 'Move to trash',
|
||||
icon: 'delete-outline',
|
||||
type: 'error',
|
||||
func: deleteItem
|
||||
|
||||
@@ -1,31 +1,24 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {ActivityIndicator, TouchableOpacity, View} from 'react-native';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { ActivityIndicator, TouchableOpacity, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import {useTracked} from '../../provider';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import {db} from '../../utils/database';
|
||||
import {
|
||||
eClosePublishNoteDialog,
|
||||
eOpenPublishNoteDialog
|
||||
} from '../../utils/Events';
|
||||
import {openLinkInBrowser} from '../../utils/functions';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import { db } from '../../utils/database';
|
||||
import { eClosePublishNoteDialog, eOpenPublishNoteDialog } from '../../utils/Events';
|
||||
import { openLinkInBrowser } from '../../utils/functions';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Input from '../Input';
|
||||
import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {useAttachmentStore} from '../../provider/stores';
|
||||
import {editing} from '../../utils';
|
||||
import { useAttachmentStore } from '../../provider/stores';
|
||||
import { editing } from '../../utils';
|
||||
|
||||
let passwordValue = null;
|
||||
const PublishNoteDialog = () => {
|
||||
@@ -39,8 +32,7 @@ const PublishNoteDialog = () => {
|
||||
const [note, setNote] = useState(null);
|
||||
const [publishing, setPublishing] = useState(false);
|
||||
const publishUrl =
|
||||
note &&
|
||||
`https://monograph.notesnook.com/${db?.monographs.monograph(note?.id)}`;
|
||||
note && `https://monograph.notesnook.com/${db?.monographs.monograph(note?.id)}`;
|
||||
const isPublished = note && db?.monographs.isPublished(note?.id);
|
||||
const pwdInput = useRef();
|
||||
|
||||
@@ -137,13 +129,15 @@ const PublishNoteDialog = () => {
|
||||
onClose={async () => {
|
||||
passwordValue = null;
|
||||
setVisible(false);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title={note.title}
|
||||
paragraph={`Anyone with the link${
|
||||
@@ -158,17 +152,16 @@ const PublishNoteDialog = () => {
|
||||
alignContent: 'center',
|
||||
height: 150,
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator size={25} color={colors.accent} />
|
||||
<Paragraph
|
||||
style={{
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Please wait...
|
||||
{loading &&
|
||||
`\nDownloading attachments (${
|
||||
loading?.current / loading?.total
|
||||
})`}
|
||||
{loading && `\nDownloading attachments (${loading?.current / loading?.total})`}
|
||||
</Paragraph>
|
||||
</View>
|
||||
) : (
|
||||
@@ -182,12 +175,14 @@ const PublishNoteDialog = () => {
|
||||
backgroundColor: colors.nav,
|
||||
padding: 12,
|
||||
borderRadius: 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.sm}>Published at:</Heading>
|
||||
<Paragraph size={SIZE.xs} numberOfLines={1}>
|
||||
{publishUrl}
|
||||
@@ -202,9 +197,9 @@ const PublishNoteDialog = () => {
|
||||
style={{
|
||||
marginTop: 5,
|
||||
color: colors.pri
|
||||
}}>
|
||||
<Icon color={colors.accent} name="open-in-new" /> Open in
|
||||
browser
|
||||
}}
|
||||
>
|
||||
<Icon color={colors.accent} name="open-in-new" /> Open in browser
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -235,7 +230,8 @@ const PublishNoteDialog = () => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginBottom: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
onPress={() => {
|
||||
if (publishing) return;
|
||||
@@ -243,22 +239,18 @@ const PublishNoteDialog = () => {
|
||||
}}
|
||||
color={isLocked ? colors.accent : colors.icon}
|
||||
size={SIZE.lg}
|
||||
name={
|
||||
isLocked
|
||||
? 'check-circle-outline'
|
||||
: 'checkbox-blank-circle-outline'
|
||||
}
|
||||
name={isLocked ? 'check-circle-outline' : 'checkbox-blank-circle-outline'}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md}>Password protection</Heading>
|
||||
<Paragraph>
|
||||
Published note can only be viewed by someone with the
|
||||
password.
|
||||
Published note can only be viewed by someone with the password.
|
||||
</Paragraph>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@@ -271,29 +263,26 @@ const PublishNoteDialog = () => {
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
onPress={() => {
|
||||
setSelfDestruct(!selfDestruct);
|
||||
}}
|
||||
color={selfDestruct ? colors.accent : colors.icon}
|
||||
size={SIZE.lg}
|
||||
name={
|
||||
selfDestruct
|
||||
? 'check-circle-outline'
|
||||
: 'checkbox-blank-circle-outline'
|
||||
}
|
||||
name={selfDestruct ? 'check-circle-outline' : 'checkbox-blank-circle-outline'}
|
||||
/>
|
||||
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
flexShrink: 1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md}>Self destruct</Heading>
|
||||
<Paragraph>
|
||||
Published note link will be automatically deleted once it is
|
||||
viewed by someone.
|
||||
Published note link will be automatically deleted once it is viewed by someone.
|
||||
</Paragraph>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
@@ -303,7 +292,8 @@ const PublishNoteDialog = () => {
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{isLocked ? (
|
||||
<>
|
||||
<Input
|
||||
@@ -357,12 +347,10 @@ const PublishNoteDialog = () => {
|
||||
}}
|
||||
onPress={async () => {
|
||||
try {
|
||||
await openLinkInBrowser(
|
||||
'https://docs.notesnook.com/monographs/',
|
||||
colors.accent
|
||||
);
|
||||
await openLinkInBrowser('https://docs.notesnook.com/monographs/', colors.accent);
|
||||
} catch (e) {}
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Learn more about Notesnook Monograph
|
||||
</Paragraph>
|
||||
</View>
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import React, {useEffect, useRef, useState} from 'react';
|
||||
import {Linking, Platform, View} from 'react-native';
|
||||
import {eSubscribeEvent, eUnSubscribeEvent} from '../../services/EventManager';
|
||||
import {eCloseRateDialog, eOpenRateDialog} from '../../utils/Events';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Linking, Platform, View } from 'react-native';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent } from '../../services/EventManager';
|
||||
import { eCloseRateDialog, eOpenRateDialog } from '../../utils/Events';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import {STORE_LINK} from '../../utils';
|
||||
import {clearMessage} from '../../services/Message';
|
||||
import { STORE_LINK } from '../../utils';
|
||||
import { clearMessage } from '../../services/Message';
|
||||
|
||||
const RateDialog = () => {
|
||||
const [visible, setVisible] = useState(false);
|
||||
@@ -51,17 +51,19 @@ const RateDialog = () => {
|
||||
);
|
||||
setVisible(false);
|
||||
clearMessage();
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
alignSelf: 'center',
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading>Do you enjoy using Notesnook?</Heading>
|
||||
<Paragraph size={SIZE.md}>
|
||||
It took us a year to bring Notesnook to life. Share your experience
|
||||
and suggestions to help us improve it.
|
||||
It took us a year to bring Notesnook to life. Share your experience and suggestions to
|
||||
help us improve it.
|
||||
</Paragraph>
|
||||
|
||||
<Seperator half />
|
||||
@@ -86,7 +88,8 @@ const RateDialog = () => {
|
||||
paddingTop: 12,
|
||||
width: '100%',
|
||||
alignSelf: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
onPress={async () => {
|
||||
await MMKV.setItem('askForRating', 'never');
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import React, {createRef} from 'react';
|
||||
import {Platform, View} from 'react-native';
|
||||
import React, { createRef } from 'react';
|
||||
import { Platform, View } from 'react-native';
|
||||
import QRCode from 'react-native-qrcode-svg';
|
||||
import Share from 'react-native-share';
|
||||
import {LOGO_BASE64} from '../../assets/images/assets';
|
||||
import { LOGO_BASE64 } from '../../assets/images/assets';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import {
|
||||
eSendEvent,
|
||||
@@ -10,22 +10,22 @@ import {
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOpenRecoveryKeyDialog, eOpenResultDialog} from '../../utils/Events';
|
||||
import {sanitizeFilename} from '../../utils/filename';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenRecoveryKeyDialog, eOpenResultDialog } from '../../utils/Events';
|
||||
import { sanitizeFilename } from '../../utils/filename';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import Storage from '../../utils/storage';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Seperator from '../Seperator';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import FileViewer from 'react-native-file-viewer';
|
||||
|
||||
import * as ScopedStorage from 'react-native-scoped-storage';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {clearMessage} from '../../services/Message';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { clearMessage } from '../../services/Message';
|
||||
|
||||
let RNFetchBlob;
|
||||
|
||||
@@ -98,24 +98,18 @@ class RecoveryKeyDialog extends React.Component {
|
||||
let path;
|
||||
RNFetchBlob = require('rn-fetch-blob').default;
|
||||
let fileName = 'nn_' + this.user.email + '_recovery_key_qrcode';
|
||||
fileName = sanitizeFilename(fileName, {replacement: '_'});
|
||||
fileName = sanitizeFilename(fileName, { replacement: '_' });
|
||||
fileName = fileName + '.png';
|
||||
|
||||
if (Platform.OS === 'android') {
|
||||
await ScopedStorage.createDocument(
|
||||
fileName,
|
||||
'image/png',
|
||||
data,
|
||||
'base64'
|
||||
);
|
||||
await ScopedStorage.createDocument(fileName, 'image/png', data, 'base64');
|
||||
} else {
|
||||
path = await Storage.checkAndCreateDir('/');
|
||||
await RNFetchBlob.fs.writeFile(path + fileName, data, 'base64');
|
||||
}
|
||||
ToastEvent.show({
|
||||
heading: 'Recovery key QR-Code saved',
|
||||
message:
|
||||
'QR-Code image has been saved to Gallery at ' + path + fileName,
|
||||
message: 'QR-Code image has been saved to Gallery at ' + path + fileName,
|
||||
type: 'success',
|
||||
context: 'local'
|
||||
});
|
||||
@@ -127,7 +121,7 @@ class RecoveryKeyDialog extends React.Component {
|
||||
try {
|
||||
let path;
|
||||
let fileName = 'nn_' + this.user?.email + '_recovery_key';
|
||||
fileName = sanitizeFilename(fileName, {replacement: '_'});
|
||||
fileName = sanitizeFilename(fileName, { replacement: '_' });
|
||||
fileName = fileName + '.txt';
|
||||
|
||||
RNFetchBlob = require('rn-fetch-blob').default;
|
||||
@@ -174,7 +168,7 @@ class RecoveryKeyDialog extends React.Component {
|
||||
try {
|
||||
if (Platform.OS === 'ios') {
|
||||
Share.open({
|
||||
url: 'file:/' + result.filePath,
|
||||
url: 'file:/' + path,
|
||||
failOnCancel: false
|
||||
}).catch(console.log);
|
||||
} else {
|
||||
@@ -188,14 +182,15 @@ class RecoveryKeyDialog extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {colors} = this.props;
|
||||
const { colors } = this.props;
|
||||
if (!this.state.visible) return null;
|
||||
return (
|
||||
<SheetWrapper
|
||||
closeOnTouchBackdrop={false}
|
||||
gestureEnabled={false}
|
||||
onOpen={this.onOpen}
|
||||
fwdRef={this.actionSheetRef}>
|
||||
fwdRef={this.actionSheetRef}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: '100%',
|
||||
@@ -204,7 +199,8 @@ class RecoveryKeyDialog extends React.Component {
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 10,
|
||||
paddingTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Save account recovery key"
|
||||
paragraph="If you forget your password, you can recover your
|
||||
@@ -216,7 +212,8 @@ class RecoveryKeyDialog extends React.Component {
|
||||
borderRadius: 5,
|
||||
padding: 12,
|
||||
marginTop: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph
|
||||
color={colors.pri}
|
||||
size={SIZE.sm}
|
||||
@@ -228,7 +225,8 @@ class RecoveryKeyDialog extends React.Component {
|
||||
paddingRight: 10,
|
||||
textAlign: 'center',
|
||||
textDecorationLine: 'underline'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{this.state.key}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -244,13 +242,14 @@ class RecoveryKeyDialog extends React.Component {
|
||||
position: 'absolute',
|
||||
opacity: 0,
|
||||
zIndex: -1
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{this.state.key ? (
|
||||
<QRCode
|
||||
getRef={this.svg}
|
||||
size={500}
|
||||
value={this.state.key}
|
||||
logo={{uri: LOGO_BASE64}}
|
||||
logo={{ uri: LOGO_BASE64 }}
|
||||
logoBorderRadius={10}
|
||||
/>
|
||||
) : null}
|
||||
@@ -314,7 +313,8 @@ class RecoveryKeyDialog extends React.Component {
|
||||
maxWidth: '100%',
|
||||
marginBottom: 5,
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
Tap twice to confirm you have saved the recovery key.
|
||||
</Paragraph>
|
||||
<Button
|
||||
|
||||
@@ -1,30 +1,26 @@
|
||||
import React, {createRef, useEffect, useState} from 'react';
|
||||
import {ActivityIndicator, Platform, View} from 'react-native';
|
||||
import React, { createRef, useEffect, useState } from 'react';
|
||||
import { ActivityIndicator, Platform, View } from 'react-native';
|
||||
import DocumentPicker from 'react-native-document-picker';
|
||||
import {FlatList} from 'react-native-gesture-handler';
|
||||
import {useTracked} from '../../provider';
|
||||
import {initialize} from '../../provider/stores';
|
||||
import {
|
||||
eSubscribeEvent,
|
||||
eUnSubscribeEvent,
|
||||
ToastEvent
|
||||
} from '../../services/EventManager';
|
||||
import {db} from '../../utils/database';
|
||||
import {eCloseRestoreDialog, eOpenRestoreDialog} from '../../utils/Events';
|
||||
import {MMKV} from '../../utils/mmkv';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { FlatList } from 'react-native-gesture-handler';
|
||||
import { useTracked } from '../../provider';
|
||||
import { initialize } from '../../provider/stores';
|
||||
import { eSubscribeEvent, eUnSubscribeEvent, ToastEvent } from '../../services/EventManager';
|
||||
import { db } from '../../utils/database';
|
||||
import { eCloseRestoreDialog, eOpenRestoreDialog } from '../../utils/Events';
|
||||
import { MMKV } from '../../utils/mmkv';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import storage from '../../utils/storage';
|
||||
import {sleep, timeConverter} from '../../utils/TimeUtils';
|
||||
import { sleep, timeConverter } from '../../utils/TimeUtils';
|
||||
import SheetWrapper from '../Sheet';
|
||||
import {Button} from '../Button';
|
||||
import { Button } from '../Button';
|
||||
import DialogHeader from '../Dialog/dialog-header';
|
||||
import Seperator from '../Seperator';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
import * as ScopedStorage from 'react-native-scoped-storage';
|
||||
import {Dialog} from '../Dialog';
|
||||
import {verifyUser} from '../../views/Settings/functions';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import {Toast} from '../Toast';
|
||||
import { Dialog } from '../Dialog';
|
||||
import { verifyUser } from '../../views/Settings/functions';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import { Toast } from '../Toast';
|
||||
|
||||
const actionSheetRef = createRef();
|
||||
let RNFetchBlob;
|
||||
@@ -71,12 +67,9 @@ const RestoreDialog = () => {
|
||||
fwdRef={actionSheetRef}
|
||||
gestureEnabled={!restoring}
|
||||
closeOnTouchBackdrop={!restoring}
|
||||
onClose={close}>
|
||||
<RestoreDataComponent
|
||||
close={close}
|
||||
restoring={restoring}
|
||||
setRestoring={setRestoring}
|
||||
/>
|
||||
onClose={close}
|
||||
>
|
||||
<RestoreDataComponent close={close} restoring={restoring} setRestoring={setRestoring} />
|
||||
<Toast context="local" />
|
||||
</SheetWrapper>
|
||||
);
|
||||
@@ -84,9 +77,9 @@ const RestoreDialog = () => {
|
||||
|
||||
export default RestoreDialog;
|
||||
|
||||
const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
const RestoreDataComponent = ({ close, setRestoring, restoring }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [files, setFiles] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [backupDirectoryAndroid, setBackupDirectoryAndroid] = useState(false);
|
||||
@@ -187,8 +180,8 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
files = await RNFetchBlob.fs.lstat(path);
|
||||
}
|
||||
files = files.sort(function (a, b) {
|
||||
timeA = a.lastModified;
|
||||
timeB = b.lastModified;
|
||||
let timeA = a.lastModified;
|
||||
let timeB = b.lastModified;
|
||||
return timeB - timeA;
|
||||
});
|
||||
setFiles(files);
|
||||
@@ -201,7 +194,7 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
}
|
||||
};
|
||||
|
||||
const renderItem = ({item, index}) => (
|
||||
const renderItem = ({ item, index }) => (
|
||||
<View
|
||||
style={{
|
||||
minHeight: 50,
|
||||
@@ -212,12 +205,14 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
flexDirection: 'row',
|
||||
borderBottomWidth: 0.5,
|
||||
borderBottomColor: colors.nav
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
maxWidth: '75%'
|
||||
}}>
|
||||
<Paragraph size={SIZE.sm} style={{width: '100%', maxWidth: '100%'}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph size={SIZE.sm} style={{ width: '100%', maxWidth: '100%' }}>
|
||||
{timeConverter(item?.lastModified * 1)}
|
||||
</Paragraph>
|
||||
<Paragraph size={SIZE.xs}>
|
||||
@@ -276,10 +271,7 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
.then(async r => {
|
||||
try {
|
||||
let backup = await r.json();
|
||||
console.log(
|
||||
'backup encrypted:',
|
||||
backup.data.iv && backup.data.salt
|
||||
);
|
||||
console.log('backup encrypted:', backup.data.iv && backup.data.salt);
|
||||
if (backup.data.iv && backup.data.salt) {
|
||||
withPassword(
|
||||
async value => {
|
||||
@@ -326,13 +318,12 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
paddingRight: 8,
|
||||
alignItems: 'center',
|
||||
paddingTop: restoring ? 8 : 0
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<DialogHeader
|
||||
title="Backups"
|
||||
paragraph={`All the backups are stored in ${
|
||||
Platform.OS === 'ios'
|
||||
? 'File Manager/Notesnook/Backups'
|
||||
: 'selected backups folder.'
|
||||
Platform.OS === 'ios' ? 'File Manager/Notesnook/Backups' : 'selected backups folder.'
|
||||
}`}
|
||||
button={button}
|
||||
/>
|
||||
@@ -351,7 +342,8 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator color={colors.accent} size={SIZE.lg} />
|
||||
</View>
|
||||
) : (
|
||||
@@ -360,16 +352,15 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{Platform.OS === 'android' && !backupDirectoryAndroid ? (
|
||||
<>
|
||||
<Button
|
||||
title="Select backups folder"
|
||||
icon="folder"
|
||||
onPress={async () => {
|
||||
let folder = await ScopedStorage.openDocumentTree(
|
||||
true
|
||||
);
|
||||
let folder = await ScopedStorage.openDocumentTree(true);
|
||||
let subfolder;
|
||||
if (folder.name !== 'Notesnook backups') {
|
||||
subfolder = await ScopedStorage.createDirectory(
|
||||
@@ -380,10 +371,7 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
subfolder = folder;
|
||||
}
|
||||
console.log(subfolder, folder);
|
||||
MMKV.setItem(
|
||||
'backupStorageDir',
|
||||
JSON.stringify(subfolder)
|
||||
);
|
||||
MMKV.setItem('backupStorageDir', JSON.stringify(subfolder));
|
||||
setBackupDirectoryAndroid(subfolder);
|
||||
setLoading(true);
|
||||
checkBackups();
|
||||
@@ -403,9 +391,9 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
}}
|
||||
size={SIZE.xs}
|
||||
textBreakStrategy="balanced"
|
||||
color={colors.icon}>
|
||||
Select the folder that includes your backup files to
|
||||
list them here.
|
||||
color={colors.icon}
|
||||
>
|
||||
Select the folder that includes your backup files to list them here.
|
||||
</Paragraph>
|
||||
</>
|
||||
) : (
|
||||
@@ -419,11 +407,10 @@ const RestoreDataComponent = ({close, setRestoring, restoring}) => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 200
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator color={colors.accent} />
|
||||
<Paragraph color={colors.icon}>
|
||||
Restoring backup. Please wait.
|
||||
</Paragraph>
|
||||
<Paragraph color={colors.icon}>Restoring backup. Please wait.</Paragraph>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,30 +1,24 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {eSendEvent} from '../../services/EventManager';
|
||||
import {
|
||||
eCloseProgressDialog,
|
||||
eCloseResultDialog,
|
||||
eOpenPremiumDialog
|
||||
} from '../../utils/Events';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import { useTracked } from '../../provider';
|
||||
import { eSendEvent } from '../../services/EventManager';
|
||||
import { eCloseProgressDialog, eCloseResultDialog, eOpenPremiumDialog } from '../../utils/Events';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
export const ProFeatures = ({count = 6}) => {
|
||||
export const ProFeatures = ({ count = 6 }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
return (
|
||||
<>
|
||||
{[
|
||||
{
|
||||
content:
|
||||
'Unlock unlimited notebooks, tags, colors. Organize like a pro'
|
||||
content: 'Unlock unlimited notebooks, tags, colors. Organize like a pro'
|
||||
},
|
||||
{
|
||||
content:
|
||||
'Attach files upto 500MB, upload 4K images with unlimited storage'
|
||||
content: 'Attach files upto 500MB, upload 4K images with unlimited storage'
|
||||
},
|
||||
{
|
||||
content: 'Instantly sync to unlimited devices'
|
||||
@@ -33,8 +27,7 @@ export const ProFeatures = ({count = 6}) => {
|
||||
content: 'A private vault to keep everything imporant always locked'
|
||||
},
|
||||
{
|
||||
content:
|
||||
'Rich note editing experience with markdown, tables, checklists and more'
|
||||
content: 'Rich note editing experience with markdown, tables, checklists and more'
|
||||
},
|
||||
{
|
||||
content: 'Export your notes in Pdf, markdown and html formats'
|
||||
@@ -43,6 +36,7 @@ export const ProFeatures = ({count = 6}) => {
|
||||
.slice(0, count)
|
||||
.map(item => (
|
||||
<View
|
||||
key={item.content}
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
width: '100%',
|
||||
@@ -52,11 +46,10 @@ export const ProFeatures = ({count = 6}) => {
|
||||
alignItems: 'center',
|
||||
borderRadius: 5,
|
||||
justifyContent: 'flex-start'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon size={SIZE.lg} color={colors.accent} name="check" />
|
||||
<Paragraph style={{marginLeft: 5, flexShrink: 1}}>
|
||||
{item.content}
|
||||
</Paragraph>
|
||||
<Paragraph style={{ marginLeft: 5, flexShrink: 1 }}>{item.content}</Paragraph>
|
||||
</View>
|
||||
))}
|
||||
<Paragraph
|
||||
@@ -70,7 +63,8 @@ export const ProFeatures = ({count = 6}) => {
|
||||
style={{
|
||||
textDecorationLine: 'underline',
|
||||
color: colors.icon
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
See all features included in Notesnook Pro
|
||||
</Paragraph>
|
||||
</>
|
||||
|
||||
@@ -15,16 +15,14 @@ import { ProFeatures } from './pro-features';
|
||||
|
||||
const ResultDialog = () => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [dialogData, setDialogData] = useState({
|
||||
title: 'Thank you for signing up!',
|
||||
paragraph:
|
||||
'Try out all features of Notesnook free for 7 days. No limitations. No commitments.',
|
||||
paragraph: 'Try out all features of Notesnook free for 7 days. No limitations. No commitments.',
|
||||
button: 'Start taking notes'
|
||||
});
|
||||
useEffect(() => {
|
||||
|
||||
eSubscribeEvent(eOpenResultDialog, open);
|
||||
eSubscribeEvent(eCloseResultDialog, close);
|
||||
return () => {
|
||||
@@ -56,7 +54,8 @@ const ResultDialog = () => {
|
||||
paddingTop: 20,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading
|
||||
size={SIZE.lg}
|
||||
textBreakStrategy="balanced"
|
||||
@@ -67,7 +66,8 @@ const ResultDialog = () => {
|
||||
maxWidth: '100%',
|
||||
marginBottom: 10,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{dialogData.title}
|
||||
</Heading>
|
||||
|
||||
@@ -79,7 +79,8 @@ const ResultDialog = () => {
|
||||
textAlign: 'center',
|
||||
maxWidth: '80%',
|
||||
lineHeight: SIZE.sm + 5
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{dialogData.paragraph}
|
||||
</Paragraph>
|
||||
|
||||
@@ -90,7 +91,8 @@ const ResultDialog = () => {
|
||||
paddingHorizontal: 12,
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ProFeatures count={4} />
|
||||
</View>
|
||||
|
||||
@@ -102,7 +104,8 @@ const ResultDialog = () => {
|
||||
borderBottomRightRadius: 10,
|
||||
borderBottomLeftRadius: 10,
|
||||
paddingVertical: 10
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
title={dialogData.button}
|
||||
width={null}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import React, {useEffect} from 'react';
|
||||
import {BackHandler, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useSelectionStore} from '../../provider/stores';
|
||||
import {eSendEvent, ToastEvent} from '../../services/EventManager';
|
||||
import React, { useEffect } from 'react';
|
||||
import { BackHandler, Platform, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSelectionStore } from '../../provider/stores';
|
||||
import { eSendEvent, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
import SearchService from '../../services/SearchService';
|
||||
import {db} from '../../utils/database';
|
||||
import {eOpenMoveNoteDialog, refreshNotesPage} from '../../utils/Events';
|
||||
import {deleteItems} from '../../utils/functions';
|
||||
import { db } from '../../utils/database';
|
||||
import { eOpenMoveNoteDialog, refreshNotesPage } from '../../utils/Events';
|
||||
import { deleteItems } from '../../utils/functions';
|
||||
import layoutmanager from '../../utils/layout-manager';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {sleep} from '../../utils/TimeUtils';
|
||||
import {ActionIcon} from '../ActionIcon';
|
||||
import {presentDialog} from '../Dialog/functions';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { sleep } from '../../utils/TimeUtils';
|
||||
import { ActionIcon } from '../ActionIcon';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
import Heading from '../Typography/Heading';
|
||||
|
||||
export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
export const SelectionHeader = React.memo(({ screen, type, extras }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const selectionMode = useSelectionStore(state => state.selectionMode);
|
||||
const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
|
||||
@@ -90,14 +90,16 @@ export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
flexDirection: 'row',
|
||||
zIndex: 999,
|
||||
paddingHorizontal: 12
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center',
|
||||
borderRadius: 100
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
customStyle={{
|
||||
justifyContent: 'center',
|
||||
@@ -125,7 +127,8 @@ export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Heading size={SIZE.md} color={colors.accent}>
|
||||
{selectedItemsList.length + ' Selected'}
|
||||
</Heading>
|
||||
@@ -136,7 +139,8 @@ export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{/* <ActionIcon
|
||||
onPress={async () => {
|
||||
// await sleep(100);
|
||||
@@ -219,9 +223,7 @@ export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
}}
|
||||
onPress={async () => {
|
||||
presentDialog({
|
||||
title: `Delete ${
|
||||
selectedItemsList.length > 1 ? 'items' : 'item'
|
||||
}`,
|
||||
title: `Delete ${selectedItemsList.length > 1 ? 'items' : 'item'}`,
|
||||
paragraph: `Are you sure you want to delete ${
|
||||
selectedItemsList.length > 1 ? 'these items?' : 'this item?'
|
||||
}`,
|
||||
@@ -257,4 +259,6 @@ export const SelectionHeader = React.memo(({screen, type, extras}) => {
|
||||
);
|
||||
});
|
||||
|
||||
SelectionHeader.displayName = 'SelectionHeader';
|
||||
|
||||
export default SelectionHeader;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {View } from 'react-native';
|
||||
import Clipboard from "@react-native-clipboard/clipboard"
|
||||
import { View } from 'react-native';
|
||||
import Clipboard from '@react-native-clipboard/clipboard';
|
||||
import Animated, { useValue } from 'react-native-reanimated';
|
||||
import { useTracked } from '../../provider';
|
||||
import {
|
||||
useMenuStore,
|
||||
useNotebookStore,
|
||||
useSelectionStore
|
||||
useSelectionStore,
|
||||
useTrashStore
|
||||
} from '../../provider/stores';
|
||||
import { openVault, ToastEvent } from '../../services/EventManager';
|
||||
import Navigation from '../../services/Navigation';
|
||||
@@ -17,9 +18,9 @@ import { ActionIcon } from '../ActionIcon';
|
||||
import { Button } from '../Button';
|
||||
import { presentDialog } from '../Dialog/functions';
|
||||
|
||||
export const ActionStrip = ({note, setActionStrip}) => {
|
||||
export const ActionStrip = ({ note, setActionStrip }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const selectionMode = useSelectionStore(state => state.selectionMode);
|
||||
const setNotebooks = useNotebookStore(state => state.setNotebooks);
|
||||
const setMenuPins = useMenuStore(state => state.setMenuPins);
|
||||
@@ -38,7 +39,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
Navigation.setRoutesToUpdate([
|
||||
Navigation.routeNames.NotesPage,
|
||||
Navigation.routeNames.Favorites,
|
||||
Navigation.routeNames.Notes,
|
||||
Navigation.routeNames.Notes
|
||||
]);
|
||||
};
|
||||
|
||||
@@ -63,7 +64,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
if (db.notes.pinned.length === 3 && !note.pinned) {
|
||||
ToastEvent.show({
|
||||
heading: 'Cannot pin more than 3 notes',
|
||||
type: 'error',
|
||||
type: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -72,7 +73,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
if (db.notebooks.pinned.length === 3 && !note.pinned) {
|
||||
ToastEvent.show({
|
||||
heading: 'Cannot pin more than 3 notebooks',
|
||||
type: 'error',
|
||||
type: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -81,7 +82,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
}
|
||||
updateNotes();
|
||||
setActionStrip(false);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Add to favorites',
|
||||
@@ -97,13 +98,11 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
setActionStrip(false);
|
||||
},
|
||||
visible: note.type === 'note',
|
||||
color: !note.favorite ? 'orange' : null,
|
||||
color: !note.favorite ? 'orange' : null
|
||||
},
|
||||
|
||||
{
|
||||
title: isPinnedToMenu
|
||||
? 'Remove Shortcut from Menu'
|
||||
: 'Add Shortcut to Menu',
|
||||
title: isPinnedToMenu ? 'Remove Shortcut from Menu' : 'Add Shortcut to Menu',
|
||||
icon: isPinnedToMenu ? 'link-variant-remove' : 'link-variant',
|
||||
onPress: async () => {
|
||||
try {
|
||||
@@ -111,20 +110,20 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
await db.settings.unpin(note.id);
|
||||
ToastEvent.show({
|
||||
heading: 'Shortcut removed from menu',
|
||||
type: 'success',
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
if (note.type === 'topic') {
|
||||
await db.settings.pin(note.type, {
|
||||
id: note.id,
|
||||
notebookId: note.notebookId,
|
||||
notebookId: note.notebookId
|
||||
});
|
||||
} else {
|
||||
await db.settings.pin(note.type, {id: note.id});
|
||||
await db.settings.pin(note.type, { id: note.id });
|
||||
}
|
||||
ToastEvent.show({
|
||||
heading: 'Shortcut added to menu',
|
||||
type: 'success',
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
setIsPinnedToMenu(db.settings.isPinned(note.id));
|
||||
@@ -133,7 +132,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
setActionStrip(false);
|
||||
} catch (e) {}
|
||||
},
|
||||
visible: note.type !== 'note',
|
||||
visible: note.type !== 'note'
|
||||
},
|
||||
{
|
||||
title: 'Copy Note',
|
||||
@@ -147,7 +146,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
locked: true,
|
||||
item: note,
|
||||
title: 'Copy note',
|
||||
description: 'Unlock note to copy to clipboard.',
|
||||
description: 'Unlock note to copy to clipboard.'
|
||||
});
|
||||
} else {
|
||||
let delta = await db.notes.note(note.id).content();
|
||||
@@ -156,11 +155,11 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
Clipboard.setString(text);
|
||||
ToastEvent.show({
|
||||
heading: 'Note copied to clipboard',
|
||||
type: 'success',
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
setActionStrip(false);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Restore ' + note.itemType,
|
||||
@@ -172,20 +171,18 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
Navigation.routeNames.Notebooks,
|
||||
Navigation.routeNames.NotesPage,
|
||||
Navigation.routeNames.Favorites,
|
||||
Navigation.routeNames.Trash,
|
||||
Navigation.routeNames.Trash
|
||||
]);
|
||||
|
||||
ToastEvent.show({
|
||||
heading:
|
||||
item.type === 'note'
|
||||
? 'Note restored from trash'
|
||||
: 'Notebook restored from trash',
|
||||
type: 'success',
|
||||
note.type === 'note' ? 'Note restored from trash' : 'Notebook restored from trash',
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
setActionStrip(false);
|
||||
},
|
||||
visible: note.type === 'trash',
|
||||
visible: note.type === 'trash'
|
||||
},
|
||||
{
|
||||
title: 'Delete' + note.itemType,
|
||||
@@ -204,13 +201,13 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
ToastEvent.show({
|
||||
heading: 'Permanantly deleted items',
|
||||
type: 'success',
|
||||
context: 'local',
|
||||
context: 'local'
|
||||
});
|
||||
},
|
||||
positiveType: 'errorShade',
|
||||
positiveType: 'errorShade'
|
||||
});
|
||||
setActionStrip(false);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Delete' + note.type,
|
||||
@@ -221,7 +218,7 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
await deleteItems(note);
|
||||
} catch (e) {}
|
||||
setActionStrip(false);
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Close',
|
||||
@@ -229,8 +226,8 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
onPress: () => setActionStrip(false),
|
||||
color: colors.light,
|
||||
bg: colors.red,
|
||||
visible: true,
|
||||
},
|
||||
visible: true
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -246,8 +243,9 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-end',
|
||||
alignItems: 'center',
|
||||
opacity: opacity,
|
||||
}}>
|
||||
opacity: opacity
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="accent"
|
||||
title="Select"
|
||||
@@ -263,36 +261,36 @@ export const ActionStrip = ({note, setActionStrip}) => {
|
||||
style={{
|
||||
borderRadius: 100,
|
||||
paddingHorizontal: 12,
|
||||
...getElevation(5),
|
||||
...getElevation(5)
|
||||
}}
|
||||
height={30}
|
||||
/>
|
||||
{actions.map(
|
||||
item =>
|
||||
item.visible ? (
|
||||
<View
|
||||
key={item.icon}
|
||||
style={{
|
||||
width: width / 1.4 / actions.length,
|
||||
height: width / 1.4 / actions.length,
|
||||
backgroundColor: item.bg || colors.nav,
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
...getElevation(5),
|
||||
marginLeft: 15,
|
||||
}}>
|
||||
<ActionIcon
|
||||
color={item.color || colors.heading}
|
||||
onPress={item.onPress}
|
||||
tooltipText={item.title}
|
||||
top={60}
|
||||
bottom={60}
|
||||
name={item.icon}
|
||||
size={width / 2.8 / actions.length}
|
||||
/>
|
||||
</View>
|
||||
) : null,
|
||||
{actions.map(item =>
|
||||
item.visible ? (
|
||||
<View
|
||||
key={item.icon}
|
||||
style={{
|
||||
width: width / 1.4 / actions.length,
|
||||
height: width / 1.4 / actions.length,
|
||||
backgroundColor: item.bg || colors.nav,
|
||||
borderRadius: 100,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
...getElevation(5),
|
||||
marginLeft: 15
|
||||
}}
|
||||
>
|
||||
<ActionIcon
|
||||
color={item.color || colors.heading}
|
||||
onPress={item.onPress}
|
||||
tooltipText={item.title}
|
||||
top={60}
|
||||
bottom={60}
|
||||
name={item.icon}
|
||||
size={width / 2.8 / actions.length}
|
||||
/>
|
||||
</View>
|
||||
) : null
|
||||
)}
|
||||
</Animated.View>
|
||||
);
|
||||
|
||||
@@ -4,10 +4,10 @@ import { useTracked } from '../../provider';
|
||||
import { useEditorStore } from '../../provider/stores';
|
||||
import { hexToRGBA } from '../../utils/ColorUtils';
|
||||
|
||||
export const Filler = ({item, background}) => {
|
||||
export const Filler = ({ item, background }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
|
||||
const { colors } = state;
|
||||
|
||||
const currentEditingNote = useEditorStore(state => state.currentEditingNote);
|
||||
|
||||
const color = 'gray';
|
||||
@@ -18,12 +18,11 @@ export const Filler = ({item, background}) => {
|
||||
position: 'absolute',
|
||||
width: '110%',
|
||||
height: '150%',
|
||||
backgroundColor:currentEditingNote === item.id ? hexToRGBA(colors[color], 0.12) : null,
|
||||
borderLeftWidth:5,
|
||||
borderLeftColor:currentEditingNote === item.id ? colors[item.color || 'accent'] : 'transparent'
|
||||
}}>
|
||||
|
||||
|
||||
</View>
|
||||
) : null
|
||||
backgroundColor: currentEditingNote === item.id ? hexToRGBA(colors[color], 0.12) : null,
|
||||
borderLeftWidth: 5,
|
||||
borderLeftColor:
|
||||
currentEditingNote === item.id ? colors[item.color || 'accent'] : 'transparent'
|
||||
}}
|
||||
></View>
|
||||
) : null;
|
||||
};
|
||||
|
||||
@@ -8,20 +8,13 @@ import { ActionStrip } from './action-strip';
|
||||
import { Filler } from './back-fill';
|
||||
import { SelectionIcon } from './selection';
|
||||
|
||||
const SelectionWrapper = ({
|
||||
children,
|
||||
item,
|
||||
background,
|
||||
onLongPress,
|
||||
onPress,
|
||||
testID,
|
||||
}) => {
|
||||
const SelectionWrapper = ({ children, item, background, onLongPress, onPress, testID }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const [actionStrip, setActionStrip] = useState(false);
|
||||
const settings = useSettingStore(state => state.settings);
|
||||
const listMode = item.type === "notebook" ? settings.notebooksListMode : settings.notesListMode
|
||||
const compactMode = (item.type === 'notebook' || item.type === 'note') && listMode === "compact"
|
||||
const listMode = item.type === 'notebook' ? settings.notebooksListMode : settings.notesListMode;
|
||||
const compactMode = (item.type === 'notebook' || item.type === 'note') && listMode === 'compact';
|
||||
|
||||
const _onLongPress = () => {
|
||||
if (history.selectedItemsList.length > 0) return;
|
||||
@@ -65,11 +58,10 @@ const SelectionWrapper = ({
|
||||
borderRadius: 0,
|
||||
overflow: 'hidden',
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical:compactMode ? 8 : 12,
|
||||
}}>
|
||||
{actionStrip ? (
|
||||
<ActionStrip note={item} setActionStrip={setActionStrip} />
|
||||
) : null}
|
||||
paddingVertical: compactMode ? 8 : 12
|
||||
}}
|
||||
>
|
||||
{actionStrip ? <ActionStrip note={item} setActionStrip={setActionStrip} /> : null}
|
||||
|
||||
{item.type === 'note' ? <Filler background={background} item={item} /> : null}
|
||||
<SelectionIcon
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {TouchableOpacity, View} from 'react-native';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { TouchableOpacity, View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {Actions} from '../../provider/Actions';
|
||||
import {useSelectionStore} from '../../provider/stores';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import { useTracked } from '../../provider';
|
||||
import { Actions } from '../../provider/Actions';
|
||||
import { useSelectionStore } from '../../provider/stores';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
|
||||
export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
export const SelectionIcon = ({ setActionStrip, item, compactMode }) => {
|
||||
const [state, dispatch] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
|
||||
const selectionMode = useSelectionStore(state => state.selectionMode);
|
||||
const selectedItemsList = useSelectionStore(state => state.selectedItemsList);
|
||||
@@ -18,9 +18,7 @@ export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
useEffect(() => {
|
||||
if (selectionMode) {
|
||||
setActionStrip(false);
|
||||
let exists = selectedItemsList.filter(
|
||||
o => o.dateCreated === item.dateCreated
|
||||
);
|
||||
let exists = selectedItemsList.filter(o => o.dateCreated === item.dateCreated);
|
||||
|
||||
if (exists[0]) {
|
||||
if (!selected) {
|
||||
@@ -34,7 +32,7 @@ export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
}
|
||||
}, [selectedItemsList, item.id]);
|
||||
|
||||
onPress = () => {
|
||||
const onPress = () => {
|
||||
setSelectedItem(item);
|
||||
};
|
||||
|
||||
@@ -44,7 +42,7 @@ export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
display: 'flex',
|
||||
opacity: 1,
|
||||
width: '10%',
|
||||
height:compactMode ? 40 : 70,
|
||||
height: compactMode ? 40 : 70,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: colors.bg,
|
||||
@@ -52,7 +50,8 @@ export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
marginRight: 10,
|
||||
borderWidth: 1,
|
||||
borderColor: selected ? colors.accent : colors.border
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<TouchableOpacity
|
||||
activeOpacity={1}
|
||||
onPress={onPress}
|
||||
@@ -60,13 +59,10 @@ export const SelectionIcon = ({setActionStrip, item,compactMode}) => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: 70
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{selected && (
|
||||
<Icon
|
||||
size={SIZE.xl}
|
||||
color={selected ? colors.accent : colors.icon}
|
||||
name="check"
|
||||
/>
|
||||
<Icon size={SIZE.xl} color={selected ? colors.accent : colors.icon} name="check" />
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import { View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
|
||||
const Seperator = ({half = false}) => {
|
||||
const Seperator = ({ half = false }) => {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
width: half ? 7.5 :15,
|
||||
height: half ? 7.5 : 15,
|
||||
width: half ? 7.5 : 15,
|
||||
height: half ? 7.5 : 15
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Seperator
|
||||
export default Seperator;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Dimensions, StyleSheet, View } from 'react-native';
|
||||
|
||||
const Circle = ({size, color, position}) => {
|
||||
const Circle = ({ size, color, position }) => {
|
||||
let style = {
|
||||
wrapper: {
|
||||
flexDirection: 'row',
|
||||
@@ -21,7 +21,7 @@ const Circle = ({size, color, position}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Donut = ({size, color, position}) => {
|
||||
const Donut = ({ size, color, position }) => {
|
||||
let style = {
|
||||
wrapper: {
|
||||
flexDirection: 'row',
|
||||
@@ -42,7 +42,7 @@ const Donut = ({size, color, position}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Triangle = ({size, color, position}) => {
|
||||
const Triangle = ({ size, color, position }) => {
|
||||
let style = {
|
||||
wrapper: {
|
||||
flexDirection: 'row',
|
||||
@@ -59,7 +59,7 @@ const Triangle = ({size, color, position}) => {
|
||||
borderLeftColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
borderBottomColor: color,
|
||||
transform: [{rotate: '180deg'}]
|
||||
transform: [{ rotate: '180deg' }]
|
||||
}
|
||||
};
|
||||
return (
|
||||
@@ -69,7 +69,7 @@ const Triangle = ({size, color, position}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const DiamondNarrow = ({size, color, position}) => {
|
||||
const DiamondNarrow = ({ size, color, position }) => {
|
||||
let style = {
|
||||
wrapper: {
|
||||
flexDirection: 'row',
|
||||
@@ -111,7 +111,7 @@ const DiamondNarrow = ({size, color, position}) => {
|
||||
);
|
||||
};
|
||||
|
||||
const CutDiamond = ({size, color, position}) => {
|
||||
const CutDiamond = ({ size, color, position }) => {
|
||||
let style = {
|
||||
wrapper: {
|
||||
flexDirection: 'row',
|
||||
@@ -153,25 +153,16 @@ const CutDiamond = ({size, color, position}) => {
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
const Shapes = ({
|
||||
primaryColor,
|
||||
secondaryColor,
|
||||
height,
|
||||
figures,
|
||||
borderRadius,
|
||||
style
|
||||
}) => {
|
||||
const Shapes = ({ primaryColor, secondaryColor, height, figures, borderRadius, style }) => {
|
||||
const config = {
|
||||
primaryColor: primaryColor || '#416DF8',
|
||||
secondaryColor: secondaryColor || '#2F53D5',
|
||||
height: Dimensions.get('window').height / (height || 3.5),
|
||||
sizefigure: 100,
|
||||
figures: figures || [
|
||||
{name: 'circle', position: 'center', size: 60},
|
||||
{name: 'donut', position: 'flex-start', axis: 'top', size: 80},
|
||||
{name: 'circle', position: 'center', axis: 'right', size: 100}
|
||||
{ name: 'circle', position: 'center', size: 60 },
|
||||
{ name: 'donut', position: 'flex-start', axis: 'top', size: 80 },
|
||||
{ name: 'circle', position: 'center', axis: 'right', size: 100 }
|
||||
],
|
||||
borderRadius: borderRadius !== undefined ? borderRadius : 30
|
||||
};
|
||||
@@ -204,32 +195,17 @@ const Shapes = ({
|
||||
|
||||
if (e.name === 'circle') {
|
||||
arrFigures.push(
|
||||
<Circle
|
||||
key={i}
|
||||
size={sizefigure}
|
||||
color={config.secondaryColor}
|
||||
position={position}
|
||||
/>
|
||||
<Circle key={i} size={sizefigure} color={config.secondaryColor} position={position} />
|
||||
);
|
||||
}
|
||||
if (e.name === 'donut') {
|
||||
arrFigures.push(
|
||||
<Donut
|
||||
key={i}
|
||||
size={sizefigure}
|
||||
color={config.secondaryColor}
|
||||
position={position}
|
||||
/>
|
||||
<Donut key={i} size={sizefigure} color={config.secondaryColor} position={position} />
|
||||
);
|
||||
}
|
||||
if (e.name === 'triangle') {
|
||||
arrFigures.push(
|
||||
<Triangle
|
||||
key={i}
|
||||
size={sizefigure}
|
||||
color={config.secondaryColor}
|
||||
position={position}
|
||||
/>
|
||||
<Triangle key={i} size={sizefigure} color={config.secondaryColor} position={position} />
|
||||
);
|
||||
}
|
||||
if (e.name === 'diamondNarrow') {
|
||||
@@ -244,12 +220,7 @@ const Shapes = ({
|
||||
}
|
||||
if (e.name === 'cutDiamond') {
|
||||
arrFigures.push(
|
||||
<CutDiamond
|
||||
key={i}
|
||||
size={sizefigure}
|
||||
color={config.secondaryColor}
|
||||
position={position}
|
||||
/>
|
||||
<CutDiamond key={i} size={sizefigure} color={config.secondaryColor} position={position} />
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -266,7 +237,8 @@ const Shapes = ({
|
||||
borderBottomLeftRadius: config.borderRadius,
|
||||
borderBottomRightRadius: config.borderRadius,
|
||||
...style
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<>{buildFigures()}</>
|
||||
</View>
|
||||
);
|
||||
@@ -284,4 +256,3 @@ const styles = StyleSheet.create({
|
||||
});
|
||||
|
||||
export { Shapes };
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import {Platform, View} from 'react-native';
|
||||
import { Platform, View } from 'react-native';
|
||||
import ActionSheet from 'react-native-actions-sheet';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useSettingStore} from '../../provider/stores';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useSettingStore } from '../../provider/stores';
|
||||
import layoutmanager from '../../utils/layout-manager';
|
||||
import {PremiumToast} from '../Premium/premium-toast';
|
||||
import {Toast} from '../Toast';
|
||||
import {BouncingView} from '../Transitions/bouncing-view';
|
||||
import { PremiumToast } from '../Premium/premium-toast';
|
||||
import { Toast } from '../Toast';
|
||||
import { BouncingView } from '../Transitions/bouncing-view';
|
||||
|
||||
const SheetWrapper = ({
|
||||
children,
|
||||
@@ -20,7 +20,7 @@ const SheetWrapper = ({
|
||||
keyboardMode
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const deviceMode = useSettingStore(state => state.deviceMode);
|
||||
const sheetKeyboardHandler = useSettingStore(state => state.sheetKeyboardHandler);
|
||||
const largeTablet = deviceMode === 'tablet';
|
||||
@@ -57,7 +57,7 @@ const SheetWrapper = ({
|
||||
}
|
||||
};
|
||||
|
||||
console.log('Sheet keyboard handler',sheetKeyboardHandler)
|
||||
console.log('Sheet keyboard handler', sheetKeyboardHandler);
|
||||
|
||||
return (
|
||||
<ActionSheet
|
||||
@@ -74,27 +74,21 @@ const SheetWrapper = ({
|
||||
indicatorColor={colors.nav}
|
||||
onOpen={_onOpen}
|
||||
keyboardDismissMode="none"
|
||||
overlayColor={pitchBlack? '#585858' : "#000000"}
|
||||
overlayColor={pitchBlack ? '#585858' : '#000000'}
|
||||
keyboardShouldPersistTaps="always"
|
||||
ExtraOverlayComponent={
|
||||
<>
|
||||
<Toast context="local" />
|
||||
<PremiumToast
|
||||
context="sheet"
|
||||
close={() => fwdRef?.current?.hide()}
|
||||
offset={50}
|
||||
/>
|
||||
<PremiumToast context="sheet" close={() => fwdRef?.current?.hide()} offset={50} />
|
||||
</>
|
||||
}
|
||||
onClose={_onClose}>
|
||||
onClose={_onClose}
|
||||
>
|
||||
<BouncingView>
|
||||
{children}
|
||||
<View
|
||||
style={{
|
||||
height:
|
||||
Platform.OS === 'ios' && insets.bottom !== 0
|
||||
? insets.bottom + 5
|
||||
: 20
|
||||
height: Platform.OS === 'ios' && insets.bottom !== 0 ? insets.bottom + 5 : 20
|
||||
}}
|
||||
/>
|
||||
</BouncingView>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import {useTracked} from '../../provider';
|
||||
import {useMessageStore, useSelectionStore} from '../../provider/stores';
|
||||
import {hexToRGBA} from '../../utils/ColorUtils';
|
||||
import {SIZE} from '../../utils/SizeUtils';
|
||||
import {PressableButton} from '../PressableButton';
|
||||
import { useTracked } from '../../provider';
|
||||
import { useMessageStore, useSelectionStore } from '../../provider/stores';
|
||||
import { hexToRGBA } from '../../utils/ColorUtils';
|
||||
import { SIZE } from '../../utils/SizeUtils';
|
||||
import { PressableButton } from '../PressableButton';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Card = ({color}) => {
|
||||
const [state,] = useTracked();
|
||||
export const Card = ({ color }) => {
|
||||
const [state] = useTracked();
|
||||
const colors = state.colors;
|
||||
color = color ? color : colors.accent;
|
||||
|
||||
@@ -27,8 +27,9 @@ export const Card = ({color}) => {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'flex-start',
|
||||
paddingHorizontal: 0,
|
||||
}}>
|
||||
paddingHorizontal: 0
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 40,
|
||||
@@ -41,7 +42,8 @@ export const Card = ({color}) => {
|
||||
borderRadius: 100,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
size={SIZE.lg}
|
||||
color={messageBoardState.type === 'error' ? colors.errorText : color}
|
||||
@@ -53,7 +55,8 @@ export const Card = ({color}) => {
|
||||
style={{
|
||||
marginLeft: 10,
|
||||
maxWidth: '70%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Paragraph color={colors.icon} size={SIZE.xs}>
|
||||
{messageBoardState.message}
|
||||
</Paragraph>
|
||||
@@ -61,7 +64,8 @@ export const Card = ({color}) => {
|
||||
style={{
|
||||
maxWidth: '100%'
|
||||
}}
|
||||
color={colors.heading}>
|
||||
color={colors.heading}
|
||||
>
|
||||
{messageBoardState.actionText}
|
||||
</Paragraph>
|
||||
</View>
|
||||
@@ -74,7 +78,8 @@ export const Card = ({color}) => {
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
right: 6
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="chevron-right"
|
||||
color={messageBoardState.type === 'error' ? colors.red : color}
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
import React from 'react';
|
||||
import {ActivityIndicator, useWindowDimensions, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
import {notesnook} from '../../../e2e/test.ids';
|
||||
import {useTracked} from '../../provider';
|
||||
import {COLORS_NOTE} from '../../utils/Colors';
|
||||
import {normalize, SIZE} from '../../utils/SizeUtils';
|
||||
import {Button} from '../Button';
|
||||
import {Placeholder} from '../ListPlaceholders';
|
||||
import { ActivityIndicator, useWindowDimensions, View } from 'react-native';
|
||||
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { notesnook } from '../../../e2e/test.ids';
|
||||
import { useTracked } from '../../provider';
|
||||
import { COLORS_NOTE } from '../../utils/Colors';
|
||||
import { normalize, SIZE } from '../../utils/SizeUtils';
|
||||
import { Button } from '../Button';
|
||||
import { Placeholder } from '../ListPlaceholders';
|
||||
import Seperator from '../Seperator';
|
||||
import Heading from '../Typography/Heading';
|
||||
import Paragraph from '../Typography/Paragraph';
|
||||
|
||||
export const Empty = ({
|
||||
loading = true,
|
||||
placeholderData,
|
||||
absolute,
|
||||
headerProps,
|
||||
type,
|
||||
screen
|
||||
}) => {
|
||||
export const Empty = ({ loading = true, placeholderData, absolute, headerProps, type, screen }) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const insets = useSafeAreaInsets();
|
||||
const {height} = useWindowDimensions();
|
||||
const { height } = useWindowDimensions();
|
||||
|
||||
return (
|
||||
<View
|
||||
@@ -34,13 +27,15 @@ export const Empty = ({
|
||||
height: height - 250 - insets.top,
|
||||
width: '100%'
|
||||
}
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
flexGrow: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Placeholder
|
||||
color={COLORS_NOTE[headerProps.color?.toLowerCase()] || colors.accent}
|
||||
w={normalize(150)}
|
||||
@@ -54,7 +49,8 @@ export const Empty = ({
|
||||
textAlign: 'center',
|
||||
width: '80%'
|
||||
}}
|
||||
color={colors.icon}>
|
||||
color={colors.icon}
|
||||
>
|
||||
{loading ? placeholderData.loading : placeholderData.paragraph}
|
||||
</Paragraph>
|
||||
<Seperator />
|
||||
@@ -68,9 +64,7 @@ export const Empty = ({
|
||||
fontSize={SIZE.md}
|
||||
accentColor="bg"
|
||||
accentText={
|
||||
COLORS_NOTE[headerProps.color?.toLowerCase()]
|
||||
? headerProps.color
|
||||
: 'accent'
|
||||
COLORS_NOTE[headerProps.color?.toLowerCase()] ? headerProps.color : 'accent'
|
||||
}
|
||||
/>
|
||||
) : loading ? (
|
||||
@@ -78,9 +72,7 @@ export const Empty = ({
|
||||
style={{
|
||||
height: 35
|
||||
}}
|
||||
color={
|
||||
COLORS_NOTE[headerProps.color?.toLowerCase()] || colors.accent
|
||||
}
|
||||
color={COLORS_NOTE[headerProps.color?.toLowerCase()] || colors.accent}
|
||||
/>
|
||||
) : (
|
||||
<View
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import {View} from 'react-native';
|
||||
import { View } from 'react-native';
|
||||
|
||||
export const Footer = () => {
|
||||
return <View style={{height: 150}} />;
|
||||
return <View style={{ height: 150 }} />;
|
||||
};
|
||||
|
||||
@@ -26,7 +26,7 @@ export const Header = React.memo(
|
||||
height
|
||||
}) => {
|
||||
const [state] = useTracked();
|
||||
const {colors} = state;
|
||||
const { colors } = state;
|
||||
const announcements = useMessageStore(state => state.announcements);
|
||||
|
||||
return announcements.length !== 0 && !noAnnouncement ? (
|
||||
@@ -39,16 +39,16 @@ export const Header = React.memo(
|
||||
width: '100%',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
{messageCard ? (
|
||||
<Card color={COLORS_NOTE[color?.toLowerCase()] || colors.accent} />
|
||||
) : null}
|
||||
}}
|
||||
>
|
||||
{messageCard ? <Card color={COLORS_NOTE[color?.toLowerCase()] || colors.accent} /> : null}
|
||||
</View>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
width: '100%'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
minHeight: height || 195,
|
||||
@@ -59,14 +59,16 @@ export const Header = React.memo(
|
||||
backgroundColor: COLORS_NOTE[color?.toLowerCase()]
|
||||
? hexToRGBA(COLORS_NOTE[color?.toLowerCase()], 0.15)
|
||||
: color || colors.shade
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
right: 0,
|
||||
paddingRight: 12,
|
||||
bottom: 0,
|
||||
position: 'absolute'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Placeholder
|
||||
color={COLORS_NOTE[color?.toLowerCase()] || colors.accent}
|
||||
w={normalize(150)}
|
||||
@@ -78,10 +80,9 @@ export const Header = React.memo(
|
||||
<View
|
||||
style={{
|
||||
marginTop: 15
|
||||
}}>
|
||||
<Heading
|
||||
style={{marginBottom: paragraph ? 0 : 0}}
|
||||
size={SIZE.xxxl * 1.2}>
|
||||
}}
|
||||
>
|
||||
<Heading style={{ marginBottom: paragraph ? 0 : 0 }} size={SIZE.xxxl * 1.2}>
|
||||
<Heading size={SIZE.xxxl * 1.2} color={colors.accent}>
|
||||
{title.slice(0, 1) === '#' ? '#' : null}
|
||||
</Heading>
|
||||
@@ -112,3 +113,5 @@ export const Header = React.memo(
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
Header.displayName = 'Header';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user