From a863df7aff98affd1cdf1a2e6b4cbb183d5a7d49 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Thu, 16 May 2024 19:54:17 -0300 Subject: [PATCH 01/16] Added flatlist --- App.js | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/App.js b/App.js index 4c282a2..784cb06 100644 --- a/App.js +++ b/App.js @@ -1,18 +1,34 @@ -import { SafeAreaView, Text } from 'react-native'; -import tw, { useDeviceContext } from 'twrnc'; +import { FlatList, SafeAreaView, Text, View } from 'react-native'; +import 'react-native-reanimated'; import { Provider } from 'react-redux'; +import tw, { useDeviceContext } from 'twrnc'; import { store } from './store'; -import 'react-native-reanimated'; + +//This is the note object. Can be added dynamically +const Note = ({item}) => { + + {item.id} + +} + +const generateData = (count) => Array.from({length : count}, (_, i) => ({id : "Lorem ipsum dolor sit amet " + i.toString()})); +const data = generateData(20); function App() { useDeviceContext(tw); + + return ( - - Your app code goes here. - + item.id} + renderItem = {({item}) => } + numColumns = {1} + contentContainerStyle={tw`p-4`} + /> ) From a06bc6eecf997a32824e3587656e8e731449b7e4 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Thu, 16 May 2024 19:56:20 -0300 Subject: [PATCH 02/16] Added flatlist --- App.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App.js b/App.js index 784cb06..72d3b9c 100644 --- a/App.js +++ b/App.js @@ -11,7 +11,7 @@ const Note = ({item}) => { } -const generateData = (count) => Array.from({length : count}, (_, i) => ({id : "Lorem ipsum dolor sit amet " + i.toString()})); +const generateData = (count) => Array.from({length : count}, (_, i) => ({id : " Lorem ipsum dolor sit amet " + i.toString()})); const data = generateData(20); function App() { From 1d63d7cdd111c856be791ae3765213e64e784df2 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 17 May 2024 11:41:35 -0300 Subject: [PATCH 03/16] Flatlist works --- App.js | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/App.js b/App.js index 72d3b9c..e5c9f0c 100644 --- a/App.js +++ b/App.js @@ -1,3 +1,4 @@ +import { NavigationContainer } from '@react-navigation/native'; import { FlatList, SafeAreaView, Text, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; @@ -6,29 +7,41 @@ import { store } from './store'; //This is the note object. Can be added dynamically const Note = ({item}) => { - - {item.id} - + return ( + + {item.note} + + ) } -const generateData = (count) => Array.from({length : count}, (_, i) => ({id : " Lorem ipsum dolor sit amet " + i.toString()})); +const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Lorem ipsum dolor sit amet"})); const data = generateData(20); -function App() { - useDeviceContext(tw); +const Stack = createNativeStackNavigator(); - +function HomeScreen({navigation}){ + return( + item.id} + renderItem = {({item}) => } + numColumns = {3} + contentContainerStyle={tw`p-4`} + /> + ) +} +function App() { + useDeviceContext(tw); return ( - item.id} - renderItem = {({item}) => } - numColumns = {1} - contentContainerStyle={tw`p-4`} - /> + + + + + + ) From b13a576e20bd8465336c06cf1dc184f53eda3898 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Sun, 19 May 2024 15:01:56 -0300 Subject: [PATCH 04/16] Navigation works --- App.js | 62 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/App.js b/App.js index e5c9f0c..81ae11b 100644 --- a/App.js +++ b/App.js @@ -1,50 +1,70 @@ import { NavigationContainer } from '@react-navigation/native'; -import { FlatList, SafeAreaView, Text, View } from 'react-native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import * as React from 'react'; +import { FlatList, SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; import { store } from './store'; -//This is the note object. Can be added dynamically -const Note = ({item}) => { - return ( - - {item.note} - - ) -} -const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Lorem ipsum dolor sit amet"})); + +const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Note number " + (i+1).toString()})); const data = generateData(20); const Stack = createNativeStackNavigator(); +//This is the note object. Can be added dynamically +const Note = ({item, nav}) => { + return ( + + {item.note} + {nav.navigate('Details', {noteText : item.note});}}> + see more... + + + ); +} + function HomeScreen({navigation}){ return( - item.id} - renderItem = {({item}) => } - numColumns = {3} - contentContainerStyle={tw`p-4`} - /> - ) + + item.id} + renderItem = {({item}) => } + numColumns = {3} + contentContainerStyle={tw`p-4`} + /> + + ); +} + +function DetailsScreen({route, navigation}){ + console.log(route.noteText); + const {noteText} = route.params; + return( + + {noteText} + + ); } function App() { useDeviceContext(tw); return ( - + - + - ) + ); } export default App; From 8b16f781c8cc0e76cd2d8fac7f88c8bd21341cd7 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Tue, 21 May 2024 13:30:51 -0300 Subject: [PATCH 05/16] New note objects can be added dynamically. --- App.js | 36 +++++++++++++++++++++++++++--------- assets/add.png | Bin 0 -> 15417 bytes 2 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 assets/add.png diff --git a/App.js b/App.js index 81ae11b..0b068cb 100644 --- a/App.js +++ b/App.js @@ -1,16 +1,17 @@ import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; -import { FlatList, SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; +import { useState } from 'react'; +import { FlatList, Image, SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; import { store } from './store'; - +//Daniel Flemming const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Note number " + (i+1).toString()})); -const data = generateData(20); +const data = generateData(0); const Stack = createNativeStackNavigator(); @@ -18,25 +19,42 @@ const Stack = createNativeStackNavigator(); const Note = ({item, nav}) => { return ( - {item.note} + {item.note} {nav.navigate('Details', {noteText : item.note});}}> - see more... + see more... ); } + + function HomeScreen({navigation}){ + const [exampleState, setExampleState] = useState(data); + const addNote = () => { + console.log("Tried adding note xd"); + var note = {id : (data.length + 1).toString(), note : "New note created!!"}; + var newNoteArray = [...data, note] + setExampleState(newNoteArray); + console.log(data); + data.push(note); + } return( item.id} renderItem = {({item}) => } numColumns = {3} contentContainerStyle={tw`p-4`} /> + + + ); } @@ -45,8 +63,8 @@ function DetailsScreen({route, navigation}){ console.log(route.noteText); const {noteText} = route.params; return( - - {noteText} + + {noteText} ); } @@ -59,7 +77,7 @@ function App() { - + diff --git a/assets/add.png b/assets/add.png new file mode 100644 index 0000000000000000000000000000000000000000..f20ec5029374ddbd69d6a55b93af0feab36f0dc5 GIT binary patch literal 15417 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 literal 0 HcmV?d00001 From 2e0753914971543cd52431ddda441ead7350fc56 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Tue, 21 May 2024 15:41:41 -0300 Subject: [PATCH 06/16] Note objects can be edited and saved. --- App.js | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/App.js b/App.js index 0b068cb..db2302f 100644 --- a/App.js +++ b/App.js @@ -2,7 +2,7 @@ import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; import { useState } from 'react'; -import { FlatList, Image, SafeAreaView, Text, TouchableOpacity, View } from 'react-native'; +import { FlatList, Image, SafeAreaView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; @@ -18,12 +18,11 @@ const Stack = createNativeStackNavigator(); //This is the note object. Can be added dynamically const Note = ({item, nav}) => { return ( - - {item.note} - {nav.navigate('Details', {noteText : item.note});}}> - see more... - - + {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> + + {item.note} + + ); } @@ -36,9 +35,9 @@ function HomeScreen({navigation}){ var note = {id : (data.length + 1).toString(), note : "New note created!!"}; var newNoteArray = [...data, note] setExampleState(newNoteArray); - console.log(data); data.push(note); } + return( { + console.log(text); + note.note = text; + } + return( - - {noteText} + + setText(text)} placeholder='Type here'>{note.note} + + SAVE NOTE + ); } From 10d78d6ca9e8f1938fa218b40056e138b5e125ec Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Tue, 21 May 2024 18:44:51 -0300 Subject: [PATCH 07/16] Homescreen bugfix --- App.js | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/App.js b/App.js index db2302f..2a59557 100644 --- a/App.js +++ b/App.js @@ -2,7 +2,7 @@ import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; import { useState } from 'react'; -import { FlatList, Image, SafeAreaView, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; @@ -16,9 +16,9 @@ const data = generateData(0); const Stack = createNativeStackNavigator(); //This is the note object. Can be added dynamically -const Note = ({item, nav}) => { +const Note = ({item, nav, updateNote}) => { return ( - {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> + {nav.navigate('Details', {note : item, updateNote: updateNote});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> {item.note} @@ -28,30 +28,34 @@ const Note = ({item, nav}) => { -function HomeScreen({navigation}){ - const [exampleState, setExampleState] = useState(data); +function HomeScreen({route, navigation}){ + const [currentData, setData] = useState(data); const addNote = () => { console.log("Tried adding note xd"); var note = {id : (data.length + 1).toString(), note : "New note created!!"}; var newNoteArray = [...data, note] - setExampleState(newNoteArray); + setData(newNoteArray); data.push(note); } - + const updateNote = () => { + setData(data); + } + return( item.id} - renderItem = {({item}) => } + renderItem = {({item}) => } numColumns = {3} + extraData={data} contentContainerStyle={tw`p-4`} /> @@ -59,21 +63,23 @@ function HomeScreen({navigation}){ } function DetailsScreen({route, navigation}){ - console.log(route.note); - const {note} = route.params; - const [text, setText] = useState(''); + + const {note, updateNote} = route.params; + + const [text, setText] = useState(note.note); saveNote = () => { - console.log(text); note.note = text; + console.log(data); + updateNote(); } return( - - setText(text)} placeholder='Type here'>{note.note} - + + setText(text)} placeholder='Type here'>{note.note} + SAVE NOTE - + ); } From bdefde23d216904e5bf6a7e9b0be8418cf34b772 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 24 May 2024 15:45:28 -0300 Subject: [PATCH 08/16] Database support added --- App.js | 53 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/App.js b/App.js index 2a59557..c374aa6 100644 --- a/App.js +++ b/App.js @@ -6,40 +6,44 @@ import { FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOp import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; +import { useAddNoteMutation, useDeleteNoteMutation, useFetchNotesQuery } from './db'; import { store } from './store'; //Daniel Flemming -const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Note number " + (i+1).toString()})); -const data = generateData(0); +//const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Note number " + (i+1).toString()})); +//const data = generateData(0); const Stack = createNativeStackNavigator(); + + //This is the note object. Can be added dynamically -const Note = ({item, nav, updateNote}) => { +const Note = ({item, nav}) => { return ( - {nav.navigate('Details', {note : item, updateNote: updateNote});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> + {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> - {item.note} + {item.content} ); } - - function HomeScreen({route, navigation}){ - const [currentData, setData] = useState(data); - const addNote = () => { - console.log("Tried adding note xd"); - var note = {id : (data.length + 1).toString(), note : "New note created!!"}; - var newNoteArray = [...data, note] - setData(newNoteArray); - data.push(note); - } - const updateNote = () => { - setData(data); + + const [addNote] = useAddNoteMutation(); + const [deleteNote] = useDeleteNoteMutation(); + const {data} = useFetchNotesQuery(); + + const deleteAllNotes = async () => { + for(const note of data){ + for(const item of note){ + console.log(item); + await deleteNote({id : item.id}); + } + } } + return( @@ -47,17 +51,22 @@ function HomeScreen({route, navigation}){ style={tw`w-full`} data = {data} keyExtractor = {(item) => item.id} - renderItem = {({item}) => } + renderItem = {({item}) => } numColumns = {3} - extraData={data} contentContainerStyle={tw`p-4`} /> - + {await addNote({content: "New note created!!"}); console.log(data)}}> + {await deleteAllNotes(); console.log(data)}}> + + ); } @@ -88,12 +97,12 @@ function App() { return ( - + - + ); From 2bdbeb3b27c0893abc1447c8169cf23ad949eeda Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 24 May 2024 16:18:26 -0300 Subject: [PATCH 09/16] Added database support for note editing --- App.js | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/App.js b/App.js index c374aa6..29ff112 100644 --- a/App.js +++ b/App.js @@ -2,11 +2,11 @@ import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; import { useState } from 'react'; -import { FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; -import { useAddNoteMutation, useDeleteNoteMutation, useFetchNotesQuery } from './db'; +import { useAddNoteMutation, useDeleteNoteMutation, useFetchNotesQuery, useUpdateNoteMutation } from './db'; import { store } from './store'; //Daniel Flemming @@ -33,29 +33,43 @@ function HomeScreen({route, navigation}){ const [addNote] = useAddNoteMutation(); const [deleteNote] = useDeleteNoteMutation(); - const {data} = useFetchNotesQuery(); + const {data, error, isLoading} = useFetchNotesQuery(); const deleteAllNotes = async () => { for(const note of data){ for(const item of note){ - console.log(item); await deleteNote({id : item.id}); } } } + if(isLoading){ + return( + + + + ); + } + + if(error){ + return( + + Failed to load notes + + ); + } return( item.id} renderItem = {({item}) => } numColumns = {3} contentContainerStyle={tw`p-4`} /> - {await addNote({content: "New note created!!"}); console.log(data)}}> + {await addNote({content: "Tap to edit"}); console.log(data)}}> { - note.note = text; - console.log(data); - updateNote(); + console.log(text); + updateNote({id : note.id, content : text}); } + return( - setText(text)} placeholder='Type here'>{note.note} + setText(text)} placeholder='Type here'>{note.content} SAVE NOTE From 066c029c2f2c2478ea769a7bef2ec61c9ab09769 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 24 May 2024 18:35:37 -0300 Subject: [PATCH 10/16] Added search feature --- App.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/App.js b/App.js index 29ff112..5524ef9 100644 --- a/App.js +++ b/App.js @@ -6,7 +6,7 @@ import { ActivityIndicator, FlatList, Image, SafeAreaView, ScrollView, Text, Tex import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; -import { useAddNoteMutation, useDeleteNoteMutation, useFetchNotesQuery, useUpdateNoteMutation } from './db'; +import { useAddNoteMutation, useDeleteNoteMutation, useFetchNotesQuery, useSearchNotesQuery, useUpdateNoteMutation } from './db'; import { store } from './store'; //Daniel Flemming @@ -34,6 +34,8 @@ function HomeScreen({route, navigation}){ const [addNote] = useAddNoteMutation(); const [deleteNote] = useDeleteNoteMutation(); const {data, error, isLoading} = useFetchNotesQuery(); + const [text, setText] = useState(""); + const {data : filteredData, isLoading : searchNotesLoading} = useSearchNotesQuery(""+text); const deleteAllNotes = async () => { for(const note of data){ @@ -43,7 +45,7 @@ function HomeScreen({route, navigation}){ } } - if(isLoading){ + if(isLoading || searchNotesLoading){ return( @@ -61,15 +63,19 @@ function HomeScreen({route, navigation}){ return( + + Search/Quick add + {setText(text)}}> + item.id} renderItem = {({item}) => } numColumns = {3} contentContainerStyle={tw`p-4`} /> - {await addNote({content: "Tap to edit"}); console.log(data)}}> + {await addNote({title : " ", content: ""+text}); console.log(data)}}> { console.log(text); - updateNote({id : note.id, content : text}); + updateNote({id : note.id, content : text, title : " "}); } From f04b3fa2d945a824e34d0bc8cff411058ae002ef Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 24 May 2024 19:12:22 -0300 Subject: [PATCH 11/16] Added a delete note feature --- App.js | 54 ++++++++++++++++++++++++++-------------------- assets/delete.png | Bin 0 -> 17660 bytes 2 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 assets/delete.png diff --git a/App.js b/App.js index 5524ef9..4177fee 100644 --- a/App.js +++ b/App.js @@ -30,21 +30,11 @@ const Note = ({item, nav}) => { } function HomeScreen({route, navigation}){ - const [addNote] = useAddNoteMutation(); - const [deleteNote] = useDeleteNoteMutation(); const {data, error, isLoading} = useFetchNotesQuery(); const [text, setText] = useState(""); const {data : filteredData, isLoading : searchNotesLoading} = useSearchNotesQuery(""+text); - const deleteAllNotes = async () => { - for(const note of data){ - for(const item of note){ - await deleteNote({id : item.id}); - } - } - } - if(isLoading || searchNotesLoading){ return( @@ -65,7 +55,7 @@ function HomeScreen({route, navigation}){ Search/Quick add - {setText(text)}}> + {setText(text)}}> - {await addNote({title : " ", content: ""+text}); console.log(data)}}> + {await addNote({title : " ", content: ""+text});}}> - - {await deleteAllNotes(); console.log(data)}}> - @@ -92,13 +76,31 @@ function HomeScreen({route, navigation}){ } function DetailsScreen({route, navigation}){ - const [updateNote] = useUpdateNoteMutation(); const {note} = route.params; const [text, setText] = useState(note.content); + const [deleteNote] = useDeleteNoteMutation(); + const deleteThisNote = () => { + deleteNote(note); + navigation.popToTop(); + } + React.useEffect(() => { + // Use `setOptions` to update the button that we previously specified + // Now the button includes an `onPress` handler to update the count + navigation.setOptions({ + headerRight: () => + + + + }); + }, [navigation]); + saveNote = () => { - console.log(text); updateNote({id : note.id, content : text, title : " "}); + navigation.popToTop(); } @@ -119,8 +121,14 @@ function App() { - - + + + + + , headerShadowVisible:false, headerTintColor: '#ffffff'}}/> diff --git a/assets/delete.png b/assets/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..1b61ff00b44bb74ec382ebdc32e22e4ffc28f0a3 GIT binary patch literal 17660 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

XZSPR>q* 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 Gt^W^F?AG1@ literal 0 HcmV?d00001 From 36e4112c65d8f835e92b46ac004bab4fe4803a74 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Tue, 28 May 2024 17:08:32 -0300 Subject: [PATCH 12/16] Example --- App.js | 2 +- app.json | 8 +++++++- eas.json | 18 ++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 eas.json diff --git a/App.js b/App.js index 4177fee..ab7dfa9 100644 --- a/App.js +++ b/App.js @@ -136,4 +136,4 @@ function App() { ); } -export default App; +export default App; \ No newline at end of file diff --git a/app.json b/app.json index fbb2022..01927c0 100644 --- a/app.json +++ b/app.json @@ -18,10 +18,16 @@ "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#ffffff" - } + }, + "package": "com.perfectoctogon.SKNotesStarter" }, "web": { "favicon": "./assets/favicon.png" + }, + "extra": { + "eas": { + "projectId": "8572402e-b966-48a4-a7d8-7c79fd4323f2" + } } } } diff --git a/eas.json b/eas.json new file mode 100644 index 0000000..7dfd688 --- /dev/null +++ b/eas.json @@ -0,0 +1,18 @@ +{ + "cli": { + "version": ">= 9.1.0" + }, + "build": { + "development": { + "developmentClient": true, + "distribution": "internal" + }, + "preview": { + "distribution": "internal" + }, + "production": {} + }, + "submit": { + "production": {} + } +} From a49fc63e11e7556e81ff415d872581f3761fc292 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Tue, 4 Jun 2024 21:13:14 -0300 Subject: [PATCH 13/16] Hotfix for title and proper text padding in menu --- App.js | 20 +++++++++----------- README.md | 25 ++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/App.js b/App.js index ab7dfa9..b644993 100644 --- a/App.js +++ b/App.js @@ -11,24 +11,21 @@ import { store } from './store'; //Daniel Flemming -//const generateData = (count) => Array.from({length : count}, (_, i) => ({id : (i + 1).toString(), note : "Note number " + (i+1).toString()})); -//const data = generateData(0); - const Stack = createNativeStackNavigator(); - - //This is the note object. Can be added dynamically const Note = ({item, nav}) => { return ( - {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-2 rounded-lg bg-[#2F0082]`]}> + {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-5 rounded-lg bg-[#2F0082]`]}> - {item.content} + {item.title.substring(0, 8) + "..."} + {item.content.substring(0,30) + "..."} ); } +// HomeScreen component handles the main functionality of adding, searching, and displaying notes function HomeScreen({route, navigation}){ const [addNote] = useAddNoteMutation(); const {data, error, isLoading} = useFetchNotesQuery(); @@ -53,7 +50,7 @@ function HomeScreen({route, navigation}){ return( - + Search/Quick add {setText(text)}}> @@ -75,9 +72,11 @@ function HomeScreen({route, navigation}){ ); } +// DetailsScreen component handles the display, editing, and deletion of a single note function DetailsScreen({route, navigation}){ const [updateNote] = useUpdateNoteMutation(); const {note} = route.params; + const [title, setTitle] = useState(note.title); const [text, setText] = useState(note.content); const [deleteNote] = useDeleteNoteMutation(); const deleteThisNote = () => { @@ -85,8 +84,6 @@ function DetailsScreen({route, navigation}){ navigation.popToTop(); } React.useEffect(() => { - // Use `setOptions` to update the button that we previously specified - // Now the button includes an `onPress` handler to update the count navigation.setOptions({ headerRight: () => @@ -99,13 +96,14 @@ function DetailsScreen({route, navigation}){ }, [navigation]); saveNote = () => { - updateNote({id : note.id, content : text, title : " "}); + updateNote({id : note.id, content : text, title : title}); navigation.popToTop(); } return( + setTitle(text)} placeholder='Type here'>{note.title} setText(text)} placeholder='Type here'>{note.content} SAVE NOTE diff --git a/README.md b/README.md index d462ea0..1c8d8a1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,26 @@ -# SKNotesStarter +# Notes Management App + +This is a simple Notes Management app built with React Native. It allows users to add, search, update, and delete notes. The app uses Redux Toolkit Query for data fetching and state management, and AsyncStorage for local data persistence. + +## Features + +- Add new notes +- Search notes by content +- Update existing notes +- Delete notes +- Delete all notes + +## Technologies Used + +- React Native +- Redux Toolkit Query +- AsyncStorage +- UUID + +## Installation + +1. Clone the repository: + ```bash + git clone https://github.com/PerfectOctogon/NotesJS.git View the [ShiftKey Labs Notion](https://shiftkeylabs.notion.site/Project-Install-Instructions-f937641104bc42e098fcfefcf7349608) for detailed installation instructions. \ No newline at end of file From 0f6c78d862cb9ebe6f2855f8dd98da67d06fccb9 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Fri, 21 Jun 2024 15:09:21 -0300 Subject: [PATCH 14/16] Version 1.2 working app --- App.js | 47 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/App.js b/App.js index b644993..f772e49 100644 --- a/App.js +++ b/App.js @@ -1,7 +1,7 @@ import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { ActivityIndicator, FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; @@ -15,11 +15,25 @@ const Stack = createNativeStackNavigator(); //This is the note object. Can be added dynamically const Note = ({item, nav}) => { + + titleCalculator = () => { + if(item.title.length >= 8){ + return item.title.substring(0, 8) + "..." + } + return item.title + } + + contentCalculator = () => { + if(item.content.length >= 8){ + return item.content.substring(0, 8) + "..." + } + return item.content + } return ( {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-5 rounded-lg bg-[#2F0082]`]}> - {item.title.substring(0, 8) + "..."} - {item.content.substring(0,30) + "..."} + {titleCalculator()} + {contentCalculator()} ); @@ -27,10 +41,17 @@ const Note = ({item, nav}) => { // HomeScreen component handles the main functionality of adding, searching, and displaying notes function HomeScreen({route, navigation}){ - const [addNote] = useAddNoteMutation(); + const [addNote, {data : addNoteData}] = useAddNoteMutation(); const {data, error, isLoading} = useFetchNotesQuery(); const [text, setText] = useState(""); const {data : filteredData, isLoading : searchNotesLoading} = useSearchNotesQuery(""+text); + + useEffect(() => { + if(addNoteData != undefined){ + navigation.navigate('Details', {note : addNoteData}); + console.log(addNoteData); + } + }, [addNoteData]) if(isLoading || searchNotesLoading){ return( @@ -96,17 +117,27 @@ function DetailsScreen({route, navigation}){ }, [navigation]); saveNote = () => { - updateNote({id : note.id, content : text, title : title}); + //updateNote({id : note.id, content : text, title : title}); navigation.popToTop(); } + updateContent = (text) => { + setText(text); + updateNote({id : note.id, content : text, title : title}); + } + + updateTitle = (text) => { + setTitle(title) + updateNote({id : note.id, content : note.content, title : text}); + } + return( - setTitle(text)} placeholder='Type here'>{note.title} - setText(text)} placeholder='Type here'>{note.content} + updateTitle(text)} placeholder='Type here'>{note.title} + updateContent(text)} placeholder='Type here'>{note.content} - SAVE NOTE + DONE ); From d5207c08564b607d7e5ed088a7b998030b067d56 Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Mon, 24 Jun 2024 13:59:24 -0300 Subject: [PATCH 15/16] Converted Flatlist to MasonryList. Version 1.3 working app --- App.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/App.js b/App.js index f772e49..8aa8ed9 100644 --- a/App.js +++ b/App.js @@ -1,8 +1,9 @@ +import MasonryList from '@react-native-seoul/masonry-list'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; import * as React from 'react'; import { useEffect, useState } from 'react'; -import { ActivityIndicator, FlatList, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, Image, SafeAreaView, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; import 'react-native-reanimated'; import { Provider } from 'react-redux'; import tw, { useDeviceContext } from 'twrnc'; @@ -17,20 +18,20 @@ const Stack = createNativeStackNavigator(); const Note = ({item, nav}) => { titleCalculator = () => { - if(item.title.length >= 8){ - return item.title.substring(0, 8) + "..." + if(item.title.length >= 40){ + return item.title.substring(0, 70) + "..." } return item.title } contentCalculator = () => { - if(item.content.length >= 8){ - return item.content.substring(0, 8) + "..." + if(item.content.length >=40){ + return item.content.substring(0, 256) + "..." } return item.content } return ( - {nav.navigate('Details', {note : item});}} style = {[tw`w-1/3 aspect-square mb-1 mr-1 p-5 rounded-lg bg-[#2F0082]`]}> + {nav.navigate('Details', {note : item});}} style = {[tw`m-1 p-5 rounded-lg bg-[#2F0082]`]}> {titleCalculator()} {contentCalculator()} @@ -75,12 +76,12 @@ function HomeScreen({route, navigation}){ Search/Quick add {setText(text)}}> - item.id} renderItem = {({item}) => } - numColumns = {3} + numColumns = {2} contentContainerStyle={tw`p-4`} /> {await addNote({title : " ", content: ""+text});}}> From 8b9b10ba8b4d231707db3f4961f302fdb152746c Mon Sep 17 00:00:00 2001 From: PerfectOctogon Date: Thu, 27 Jun 2024 14:40:39 -0300 Subject: [PATCH 16/16] Fixed appsaving feature --- App.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/App.js b/App.js index 8aa8ed9..e0f1d8e 100644 --- a/App.js +++ b/App.js @@ -101,7 +101,9 @@ function DetailsScreen({route, navigation}){ const [title, setTitle] = useState(note.title); const [text, setText] = useState(note.content); const [deleteNote] = useDeleteNoteMutation(); + noteDelete = false; const deleteThisNote = () => { + noteDelete = true; deleteNote(note); navigation.popToTop(); } @@ -115,29 +117,29 @@ function DetailsScreen({route, navigation}){ /> }); - }, [navigation]); + const unsubscribe = navigation.addListener('beforeRemove', (e) => { + // Prevent default behavior of leaving the screen + e.preventDefault(); + // Save the note before leaving + if(!noteDelete) + {saveNote();} + // Manually trigger the default behavior + navigation.dispatch(e.data.action); + }); - saveNote = () => { - //updateNote({id : note.id, content : text, title : title}); - navigation.popToTop(); - } + return unsubscribe; + }, [navigation, title, text]); - updateContent = (text) => { - setText(text); + saveNote = () => { updateNote({id : note.id, content : text, title : title}); + //navigation.popToTop(); } - updateTitle = (text) => { - setTitle(title) - updateNote({id : note.id, content : note.content, title : text}); - } - - return( - updateTitle(text)} placeholder='Type here'>{note.title} - updateContent(text)} placeholder='Type here'>{note.content} - + setTitle(text)} placeholder='Type here'>{note.title} + setText(text)} placeholder='Type here'>{note.content} + DONE