feat: add favorite, pin& restore function.

This commit is contained in:
ammarahm-ed
2020-01-07 11:12:55 +05:00
parent cabaf134b3
commit 4a5069f2be
6 changed files with 650 additions and 56 deletions

View File

@@ -140,6 +140,7 @@ export const AddNotebookDialog = ({visible, close, toEdit = null}) => {
animationType="fade"
onShow={() => {
refs = [];
if (toEdit !== null) {
let topicsList = [];
toEdit.topics.forEach(item => {
@@ -234,6 +235,7 @@ export const AddNotebookDialog = ({visible, close, toEdit = null}) => {
offset: 50 * index,
index,
})}
keyExtractor={(item, index) => item + index}
renderItem={({item, index}) => (
<TopicItem
item={item}

View File

@@ -68,7 +68,7 @@ export const Dialog = ({
color: colors.accent,
fontFamily: WEIGHT.bold,
marginLeft: 5,
fontSize: SIZE.md + 2,
fontSize: SIZE.md,
}}>
{title}
</Text>

View File

@@ -8,6 +8,7 @@ import {
} from 'react-native';
import {COLOR_SCHEME, SIZE, br, ph, pv, WEIGHT} from '../../common/common';
import Icon from 'react-native-vector-icons/Feather';
import {
timeSince,
ToastEvent,
@@ -225,8 +226,8 @@ const NoteItem = props => {
<Icon
style={{marginLeft: 10}}
name="star"
size={SIZE.xs}
color={colors.icon}
size={SIZE.xs + 1}
color="orange"
/>
) : null}
<Text
@@ -302,7 +303,14 @@ const NoteItem = props => {
<>
<MenuItem
onPress={() => {
show = 'topic';
db.restoreItem(item.dateCreated);
ToastEvent.show(
item.type == 'note' ? 'Note restored' : 'Notebook restored',
'success',
1000,
() => {},
'',
);
hideMenu();
}}
textStyle={{
@@ -315,6 +323,7 @@ const NoteItem = props => {
<MenuItem
onPress={() => {
show = 'topic';
hideMenu();
}}
textStyle={{
@@ -327,24 +336,18 @@ const NoteItem = props => {
</>
) : (
<>
<MenuItem
textStyle={{
color: colors.pri,
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
}}>
Pin
</MenuItem>
<MenuItem
onPress={() => {
hideMenu();
db.pinItem(item.type, item.dateCreated);
props.refresh();
ToastEvent.show(
'Note added to favorites.',
'success',
`Note ${item.pinned ? 'unpinned' : 'pinned'}`,
item.pinned ? 'error' : 'success',
3000,
() => {},
'Ok',
'',
);
}}
textStyle={{
@@ -353,7 +356,29 @@ const NoteItem = props => {
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
}}>
Favorite
{item.pinned ? 'Unpin' : 'Pin'}
</MenuItem>
<MenuItem
onPress={() => {
hideMenu();
db.favoriteItem(item.type, item.dateCreated);
props.refresh();
ToastEvent.show(
`Note ${item.favorite ? 'removed' : 'added'} to favorites.`,
item.favorite ? 'error' : 'success',
3000,
() => {},
'',
);
}}
textStyle={{
color: colors.pri,
fontFamily: WEIGHT.regular,
fontSize: SIZE.sm,
}}>
{item.favorite ? 'Unfavorite' : 'Favorite'}
</MenuItem>
<MenuItem

View File

@@ -1,4 +1,4 @@
import React, {useState} from 'react';
import React, {useState, useEffect} from 'react';
import {
View,
Text,
@@ -9,7 +9,7 @@ import {
} from 'react-native';
import {SIZE, WEIGHT} from '../../common/common';
import NoteItem from '../NoteItem';
import {DDS} from '../../../App';
import {DDS, db} from '../../../App';
import * as Animatable from 'react-native-animatable';
import {useAppContext} from '../../provider/useAppContext';
import Icon from 'react-native-vector-icons/Feather';
@@ -26,7 +26,7 @@ export const NotesList = ({
}) => {
const {colors} = useAppContext();
const [numColumns, setNumColumns] = useState(1);
const [pinned, setPinned] = useState([]);
const slideRight = {
0: {
transform: [{translateX: -4}],
@@ -50,6 +50,12 @@ export const NotesList = ({
},
};
useEffect(() => {
let pinnedItems = db.getPinned();
setPinned([...pinnedItems]);
}, [notes]);
return isGrouped ? (
<SectionList
sections={notes}
@@ -285,21 +291,9 @@ export const NotesList = ({
}}>
{notes[0] ? (
<>
{/* <NoteItem
customStyle={{
backgroundColor: colors.shade,
width: '100%',
paddingHorizontal: '5%',
paddingTop: 20,
marginBottom: 10,
marginTop: 20,
borderBottomWidth: 0,
}}
pinned={true}
item={notes[0].data[0]}
numColumns={1}
index={0}
/>
<FlatList
data={pinned}
renderItem={({item, index}) => (
<NoteItem
customStyle={{
backgroundColor: colors.shade,
@@ -311,10 +305,13 @@ export const NotesList = ({
borderBottomWidth: 0,
}}
pinned={true}
item={notes[0].data[1]}
refresh={() => refresh()}
item={item}
numColumns={1}
index={0}
/> */}
index={index}
/>
)}
/>
</>
) : null}
</View>

View File

@@ -104,6 +104,7 @@ export const Header = ({
}}>
<Animatable.View
transition="opacity"
useNativeDriver={true}
duration={500}
style={{
opacity: hide ? 1 : 0,
@@ -117,7 +118,7 @@ export const Header = ({
width: 60,
paddingRight: 0,
}}>
<Icon name={'search'} size={SIZE.xl} color={colors.icon} />
<Icon name={'search'} size={SIZE.xl} color={colors.pri} />
</TouchableOpacity>
</Animatable.View>
{verticalMenu ? (
@@ -129,7 +130,38 @@ export const Header = ({
width: 60,
paddingRight: 0,
}}>
<Icon name="more-vertical" size={SIZE.xl} color={colors.pri} />
<Icon
style={{
position: 'absolute',
transform: [
{
translateX: 0,
},
{
translateY: 3,
},
],
}}
name="arrow-down"
size={SIZE.lg}
color={colors.pri}
/>
<Icon
style={{
position: 'absolute',
transform: [
{
translateX: -15,
},
{
translateY: -3,
},
],
}}
name="arrow-up"
size={SIZE.lg}
color={colors.pri}
/>
</TouchableOpacity>
) : null}
</View>

View File

@@ -5,6 +5,7 @@ import {
Dimensions,
SafeAreaView,
FlatList,
View,
} from 'react-native';
import {SIZE, ph, pv, opacity, WEIGHT} from '../../common/common';
import Icon from 'react-native-vector-icons/Feather';
@@ -13,32 +14,569 @@ import NoteItem from '../../components/NoteItem';
import {useAppContext} from '../../provider/useAppContext';
import {db} from '../../../App';
import {NotebookItem} from '../../components/NotebookItem';
import {Dialog} from '../../components/Dialog';
import {ToastEvent} from '../../utils/utils';
import * as Animatable from 'react-native-animatable';
export const Trash = ({navigation}) => {
const {colors} = useAppContext();
const [trash, setTrash] = useState([]);
const [dialog, setDialog] = useState(false);
useEffect(() => {
let allTrash = db.getTrash();
setTrash([...allTrash]);
}, []);
const slideRight = {
0: {
transform: [{translateX: -4}],
},
0.5: {
transform: [{translateX: 0}],
},
1: {
transform: [{translateX: 4}],
},
};
const slideLeft = {
0: {
transform: [{translateX: 4}],
},
0.5: {
transform: [{translateX: 0}],
},
1: {
transform: [{translateX: -4}],
},
};
const rotate = {
0: {
transform: [{rotateZ: '0deg'}, {translateX: 0}, {translateY: 0}],
},
0.5: {
transform: [{rotateZ: '25deg'}, {translateX: 10}, {translateY: -20}],
},
1: {
transform: [{rotateZ: '45deg'}, {translateX: 10}, {translateY: -20}],
},
};
const deleteItems = (tX, tY) => {
return {
0: {
transform: [{translateX: tX}, {translateY: tY}],
},
0.3: {
transform: [{translateX: 0}, {translateY: 0}],
},
0.5: {
transform: [{translateX: 0}, {translateY: 50}],
},
1: {
transform: [{translateX: 0}, {translateY: 110}],
},
};
};
const opacity = {
0: {
opacity: 0,
},
1: {
opacity: 1,
},
};
return (
<SafeAreaView
style={{
backgroundColor: colors.bg,
height: '100%',
}}>
<Dialog
title="Empty Trash"
visible={dialog}
close={() => {
setDialog(false);
}}
icon="trash"
paragraph="Clearing all trash cannot be undone."
positiveText="Clear"
negativeText="Cancel"
positivePress={async () => {
await db.clearTrash();
let allTrash = db.getTrash();
setTrash([...allTrash]);
ToastEvent.show('Trash cleared', 'success', 1000, () => {}, '');
setDialog(false);
}}
negativePress={() => {
setDialog(false);
}}
/>
<Header colors={colors} heading="Trash" canGoBack={false} menu={true} />
<FlatList
numColumns={1}
keyExtractor={item => item.dateCreated.toString()}
style={{
width: '100%',
alignSelf: 'center',
height: '100%',
}}
contentContainerStyle={{
height: '100%',
}}
data={trash}
ListEmptyComponent={
<View
style={{
height: '80%',
width: '100%',
alignItems: 'center',
alignSelf: 'center',
justifyContent: 'center',
opacity: 0.8,
}}>
<View
style={{
alignItems: 'center',
}}>
<Animatable.View
animation={deleteItems(-50, -100)}
iterationCount="infinite"
duration={3000}
iterationDelay={4500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
width: 30,
height: 30,
backgroundColor: colors.errorBg,
borderRadius: 5,
transform: [
{
translateX: -50,
},
{
translateY: -100,
},
],
}}
/>
<Animatable.View
animation={deleteItems(-80, -70)}
iterationCount="infinite"
duration={3000}
iterationDelay={4500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
width: 25,
height: 25,
backgroundColor: colors.errorBg,
borderRadius: 5,
transform: [
{
translateX: -80,
},
{
translateY: -70,
},
],
}}
/>
<Animatable.View
animation={deleteItems(-120, -50)}
iterationCount="infinite"
duration={3000}
iterationDelay={4500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
width: 40,
height: 40,
backgroundColor: colors.errorBg,
borderRadius: 5,
transform: [
{
translateX: -120,
},
{
translateY: -50,
},
],
}}
/>
<Animatable.View
animation={deleteItems(-120, -140)}
iterationCount="infinite"
duration={3000}
iterationDelay={4500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
width: 20,
height: 20,
backgroundColor: colors.errorBg,
borderRadius: 5,
transform: [
{
translateX: -120,
},
{
translateY: -140,
},
],
}}
/>
<Animatable.View
animation={rotate}
iterationCount="infinite"
duration={3000}
iterationDelay={3500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
width: 100,
height: 15,
backgroundColor: colors.accent,
borderRadius: 100,
marginBottom: 2,
alignItems: 'center',
zIndex: 10,
}}>
<View
style={{
width: 25,
height: 10,
backgroundColor: colors.accent,
borderTopRightRadius: 5,
borderTopLeftRadius: 5,
marginBottom: 2,
marginTop: -9,
}}
/>
</Animatable.View>
<View
style={{
backgroundColor: 'white',
}}>
<View
style={{
width: 80,
height: 100,
backgroundColor: colors.shade,
borderRadius: 5,
zIndex: 10,
}}>
<Animatable.View
animation={opacity}
iterationCount="infinite"
duration={3000}
iterationDelay={4500}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
flexDirection: 'row',
width: '90%',
alignSelf: 'center',
justifyContent: 'space-around',
alignItems: 'center',
height: '100%',
}}>
<View
style={{
width: 12,
height: 80,
backgroundColor: colors.accent,
borderRadius: 5,
zIndex: 10,
}}
/>
<View
style={{
width: 12,
height: 80,
backgroundColor: colors.accent,
borderRadius: 5,
zIndex: 10,
}}
/>
<View
style={{
width: 12,
height: 80,
backgroundColor: colors.accent,
borderRadius: 5,
zIndex: 10,
}}
/>
</Animatable.View>
</View>
</View>
</View>
{/*
<Animatable.View
animation={slideRight}
iterationCount="infinite"
duration={3000}
iterationDelay={0}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
backgroundColor: colors.shade,
width: '50%',
padding: 5,
borderRadius: 5,
marginBottom: 10,
}}>
<Icon
name="trash"
size={SIZE.xl}
color={colors.accent}
style={{
position: 'absolute',
right: 5,
bottom: 0,
}}
/>
<View
style={{
width: '90%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginBottom: 8,
}}
/>
<View
style={{
width: '70%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginBottom: 8,
}}
/>
<View
style={{
flexDirection: 'row',
}}>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
marginRight: '5%',
}}
/>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
}}
/>
</View>
</Animatable.View>
<Animatable.View
animation={slideLeft}
iterationCount="infinite"
duration={3000}
iterationDelay={0}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
backgroundColor: colors.shade,
width: '50%',
padding: 5,
borderRadius: 5,
marginBottom: 10,
}}>
<Icon
name="trash"
size={SIZE.xl}
color={colors.accent}
style={{
position: 'absolute',
right: 5,
bottom: 0,
}}
/>
<View
style={{
width: '50%',
height: 15,
borderRadius: 100,
backgroundColor: colors.accent,
marginBottom: 8,
}}
/>
<View
style={{
width: '70%',
height: 10,
marginBottom: 8,
flexDirection: 'row',
}}>
<View
style={{
width: '30%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginRight: 8,
}}
/>
<View
style={{
width: '30%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginRight: 8,
}}
/>
<View
style={{
width: '30%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginRight: 8,
}}
/>
</View>
<View
style={{
flexDirection: 'row',
}}>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
marginRight: '5%',
}}
/>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
}}
/>
</View>
</Animatable.View>
<Animatable.View
animation={slideRight}
iterationCount="infinite"
duration={3000}
iterationDelay={0}
direction="alternate"
easing="ease-in"
useNativeDriver={true}
style={{
backgroundColor: colors.shade,
width: '50%',
padding: 5,
borderRadius: 5,
marginBottom: 10,
}}>
<Icon
name="trash"
size={SIZE.xl}
color={colors.accent}
style={{
position: 'absolute',
right: 5,
bottom: 0,
}}
/>
<View
style={{
width: '90%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginBottom: 8,
}}
/>
<View
style={{
width: '70%',
height: 10,
borderRadius: 5,
backgroundColor: colors.accent,
marginBottom: 8,
}}
/>
<View
style={{
flexDirection: 'row',
}}>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
marginRight: '5%',
}}
/>
<View
style={{
width: '15%',
height: 8,
borderRadius: 5,
backgroundColor: colors.icon,
}}
/>
</View>
</Animatable.View>
*/}
<Text
style={{
color: colors.icon,
fontSize: SIZE.md,
fontFamily: WEIGHT.regular,
marginTop: 20,
}}>
Deleted notes & notebooks appear here.
</Text>
<Text
style={{
fontSize: SIZE.sm,
color: colors.icon,
marginTop: 20,
}}>
Trash is empty
</Text>
</View>
}
renderItem={({item, index}) =>
item.type === 'note' ? (
<NoteItem item={item} index={index} isTrash={true} />
@@ -50,7 +588,7 @@ export const Trash = ({navigation}) => {
<TouchableOpacity
activeOpacity={opacity}
onPress={() => {
setAddNotebook(true);
setDialog(true);
}}
style={{
borderRadius: 5,
@@ -71,7 +609,7 @@ export const Trash = ({navigation}) => {
fontFamily: WEIGHT.regular,
color: 'white',
}}>
{' '}Clear all Trash
{' '}Clear all trash
</Text>
</TouchableOpacity>
</SafeAreaView>