aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/CategoryView.js61
-rw-r--r--components/DrawerContent.js43
-rw-r--r--components/NoteView.js155
-rw-r--r--components/NotesList.js185
-rw-r--r--components/Options.js68
5 files changed, 512 insertions, 0 deletions
diff --git a/components/CategoryView.js b/components/CategoryView.js
new file mode 100644
index 0000000..a9c6222
--- /dev/null
+++ b/components/CategoryView.js
@@ -0,0 +1,61 @@
+import * as React from 'react';
+import { SafeAreaView, TextInput, StyleSheet, Text, TouchableOpacity } from 'react-native';
+import * as SecureStore from 'expo-secure-store';
+
+export default function CategoryView() {
+ let [name, setName] = React.useState("")
+ const ti = React.createRef()
+
+ async function addCategory() {
+ let nk = await SecureStore.getItemAsync('categories')
+ let categories = []
+ if (!nk) categories = ["default"]; else categories = JSON.parse(nk);
+ if (!categories.find(c => c === name))
+ categories.push(name)
+ await SecureStore.setItemAsync('categories', JSON.stringify(categories))
+
+ ti.current.clear()
+
+ // props.navigation.navigate('s1')
+ }
+ return (
+ <SafeAreaView style={styles.cont}>
+ <TextInput
+ underlineColorAndroid="#FFFFFF"
+ placeholder="NAME..."
+ placeholderTextColor="#FFFFFF"
+ onChangeText={setName}
+ style={styles.input}
+ ref={ti}
+ />
+ <TouchableOpacity onPress={addCategory}><Text style={styles.txt}>Add</Text></TouchableOpacity>
+ </SafeAreaView>
+ )
+}
+
+const styles = StyleSheet.create({
+ cont: {
+ flex: 1,
+ backgroundColor: "black",
+ padding: 20,
+ alignItems: "center"
+ },
+ ico: {
+ width: 200,
+ height: 200,
+ },
+ txt: {
+ fontSize: 30,
+ fontWeight: "bold",
+ color: "#FFFFFF"
+ },
+ input: {
+ height: 40,
+ width: "100%",
+ margin: 12,
+ borderWidth: 1,
+ padding: 10,
+ color: "#FFFFFF",
+ }
+})
+
diff --git a/components/DrawerContent.js b/components/DrawerContent.js
new file mode 100644
index 0000000..41b67cb
--- /dev/null
+++ b/components/DrawerContent.js
@@ -0,0 +1,43 @@
+import * as React from "react"
+import { Image, Alert, StyleSheet } from 'react-native'
+import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
+
+import icon from "../assets/pencil-circle.png"
+import iIcon from "../assets/i.png"
+import cIcon from "../assets/text-plus-icon.png"
+import plusIcon from "../assets/plus.png"
+import newIcon from "../assets/new-icon.png"
+
+export default function DrawerContent(props) {
+ window.navigation = props.navigation
+ return (
+ <DrawerContentScrollView {...props}>
+ <Image source={icon} style={styles.topImg} />
+ <DrawerItem
+ label="Notes list"
+ icon={() => <Image source={newIcon} style={styles.icon} />}
+ onPress={() => props.navigation.navigate("notesList")}
+ />
+ <DrawerItem
+ label="Add note"
+ icon={() => <Image source={plusIcon} style={styles.icon} />}
+ onPress={() => props.navigation.navigate("addNote")}
+ />
+ <DrawerItem
+ label="Add category"
+ icon={() => <Image source={cIcon} style={styles.icon} />}
+ onPress={() => props.navigation.navigate("addCategory")}
+ />
+ <DrawerItem
+ label="Info"
+ icon={() => <Image source={iIcon} style={styles.icon} />}
+ onPress={() => Alert.alert("Alert", "Alerting from best note app, version 2.0")}
+ />
+ </DrawerContentScrollView>
+ );
+}
+
+const styles = StyleSheet.create({
+ topImg: { width: 100, height: 100, margin: 30, alignSelf: "center" },
+ icon: { width: 30, height: 30 },
+})
diff --git a/components/NoteView.js b/components/NoteView.js
new file mode 100644
index 0000000..820eaf9
--- /dev/null
+++ b/components/NoteView.js
@@ -0,0 +1,155 @@
+import * as React from 'react';
+import { SafeAreaView, TextInput, StyleSheet, Text, TouchableOpacity, Dimensions } from 'react-native';
+import { Picker } from '@react-native-picker/picker';
+import * as SecureStore from 'expo-secure-store';
+
+export default class NoteView extends React.Component {
+ constructor(props) {
+ super(props)
+ const note = props.route.params?.note ?? {};
+ this.state = {
+ note: note,
+ isNew: Object.keys(note).length === 0,
+ title: note.title ?? "",
+ body: note.body ?? "",
+ category: note.category ?? "",
+ ti1: React.createRef(),
+ ti2: React.createRef(),
+ categories: [],
+ }
+ this.setTitle = this.setTitle.bind(this)
+ this.setBody = this.setBody.bind(this)
+ this.setCategory = this.setCategory.bind(this)
+ this.setCategories = this.setCategories.bind(this)
+ this.addNote = this.addNote.bind(this)
+ this.funkcja = () => null;
+ }
+ componentDidMount() {
+ const a = () => {
+ const n = this.props.route.params?.note ?? {};
+ getCategories(this.setCategories, this.setCategory, this.state.category)
+ console.log('note', n, ' ', Date.now())
+ this.setState({ note: n })
+ this.setTitle(n.title ?? "")
+ this.setBody(n.body ?? "")
+ this.setCategory(n.category ?? "")
+ }
+ a()
+ this.props.navigation.addListener('focus', a)
+ }
+ componentWillUnmount() {
+ this.funkcja();
+ }
+
+ setTitle(t) { this.setState({ title: t }) }
+ setBody(t) { this.setState({ body: t }) }
+ setCategory(t) { this.setState({ category: t }) }
+ setCategories(t) { this.setState({ categories: t }) }
+
+ async addNote() {
+ try {
+ let nk = await SecureStore.getItemAsync('notesKeys')
+ let notesKeys = []
+ if (!nk) notesKeys = [0]; else notesKeys = JSON.parse(nk);
+ const key = this.state.isNew ? Math.max(...notesKeys) + 1 : this.state.note.key;
+ const date = Date.now();
+ const colors = ["darkred", "darkblue", "darkcyan", "darkgreen"]
+ const color = this.state.isNew ? colors[Math.floor(Math.random() * colors.length)] : this.state.note.color
+ if (this.state.isNew)
+ notesKeys.push(key);
+ let [title, body, category] = [this.state.title, this.state.body, this.state.category]
+ if (category === "") category = this.state.categories[0]
+ await SecureStore.setItemAsync(key.toString(), JSON.stringify({ title, body, date, color, key, category }))
+ await SecureStore.setItemAsync('notesKeys', JSON.stringify(notesKeys.filter(el => el !== 0)))
+ console.log(key.toString(), JSON.stringify({ title, body, date, color, key, category }))
+ console.log('notesKeys', JSON.stringify(notesKeys.filter(el => el !== 0)))
+ console.log('categories', this.state.categories)
+
+ // this.state.ti1.current.clear()
+ // this.state.ti2.current.clear()
+
+ this.props.navigation.navigate('notesList')
+ } catch (e) {
+ console.error(e)
+ }
+ }
+ render() {
+ return (
+ <SafeAreaView style={styles.cont}>
+ <TextInput
+ underlineColorAndroid="#FFFFFF"
+ placeholder="TITLE..."
+ placeholderTextColor="#FFFFFF"
+ onChangeText={this.setTitle}
+ value={this.state.title}
+ style={styles.input}
+ ref={this.state.ti1}
+ />
+ <TextInput
+ underlineColorAndroid="#FFFFFF"
+ placeholder="BODY..."
+ placeholderTextColor="#FFFFFF"
+ onChangeText={this.setBody}
+ value={this.state.body}
+ style={styles.input}
+ multiline={true}
+ ref={this.state.ti2}
+ />
+ <Picker
+ selectedValue={this.state.category}
+ onValueChange={(v, _) => this.setCategory(v)}
+ style={styles.picker}
+ itemStyle={styles.pickerItem}
+ >
+ {this.state.categories.map((c, i) => <Picker.Item value={c} label={c} key={i} />)}
+ </Picker>
+ <TouchableOpacity onPress={this.addNote}><Text style={styles.txt}>{this.state.isNew ? "Add" : "Confirm"}</Text></TouchableOpacity>
+ </SafeAreaView>
+ )
+ }
+}
+async function getCategories(setCategories, setCategory, category) {
+ let categories = await SecureStore.getItemAsync('categories')
+ if (!categories) categories = ["default"]; else categories = JSON.parse(categories);
+ setCategories(categories);
+ if (category === "")
+ setCategory(categories[0])
+}
+
+const styles = StyleSheet.create({
+ cont: {
+ flex: 1,
+ backgroundColor: "black",
+ padding: 20,
+ alignItems: "center"
+ },
+ ico: {
+ width: 200,
+ height: 200,
+ },
+ txt: {
+ fontSize: 30,
+ fontWeight: "bold",
+ color: "#FFFFFF"
+ },
+ picker: {
+ color: "white",
+ borderColor: "white",
+ width: 200,
+ height: 30,
+ backgroundColor: "darkgrey",
+ margin: 15,
+ },
+ pickerItem: {
+ backgroundColor: "black",
+ color: "white",
+ },
+ input: {
+ // height: 40,
+ width: "100%",
+ margin: 12,
+ borderWidth: 1,
+ padding: 10,
+ color: "#FFFFFF",
+ }
+})
diff --git a/components/NotesList.js b/components/NotesList.js
new file mode 100644
index 0000000..9525b11
--- /dev/null
+++ b/components/NotesList.js
@@ -0,0 +1,185 @@
+import * as React from 'react';
+import { View, StyleSheet, Text, FlatList, TouchableOpacity, Alert, TextInput } from 'react-native';
+import * as SecureStore from 'expo-secure-store';
+
+import { getFont } from "./Options"
+
+export default class NotesList extends React.Component {
+ constructor(props) {
+ super(props)
+ this.state = {
+ notes: [],
+ search: '',
+ font: 0,
+ sortOrder: true,
+ }
+ this.setNotes = this.setNotes.bind(this)
+ this.setSearch = this.setSearch.bind(this)
+ this.setFont = this.setFont.bind(this)
+ this.setSortOrder = this.setSortOrder.bind(this)
+ this.funkcja = () => null;
+ }
+ setNotes(s) { this.setState({ notes: s }) }
+ setSearch(s) { this.setState({ search: s }) }
+ setFont(s) { this.setState({ font: s }) }
+ setSortOrder(s) { this.setState({ sortOrder: s }) }
+
+ componentDidMount() {
+ getNotes(this.setNotes); getFont(this.setFont);
+ this.props.navigation.addListener('focus', () => { getNotes(this.setNotes); getFont(this.setFont); })
+ }
+ componentWillUnmount() {
+ this.funkcja();
+ }
+ render() {
+ const filterNotes = (n) => {
+ return n.title.includes(this.state.search) ||
+ n.body.includes(this.state.search) ||
+ n.category.includes(this.state.search)
+ }
+ const sortNotes = (a, b) => {
+ return this.state.sortOrder ? a.date - b.date : b.date - a.date;
+ }
+ return (
+ <View style={styles.cont} >
+ <View>
+ <TextInput
+ placeholder="SEARCH IN NOTES..."
+ placeholderTextColor="#FFFFFF"
+ onChangeText={this.setSearch}
+ style={styles.input}
+ defaultValue={this.state.search}
+ // ref={ti}
+ />
+ </View>
+ <TouchableOpacity style={styles.btn} onPress={() => this.setSortOrder(!this.state.sortOrder)}><Text style={[styles.txt, { textAlign: "center" }]}>Change sort order</Text></TouchableOpacity>
+ <View>
+ <FlatList
+ data={this.state.notes.filter(filterNotes).sort(sortNotes)}
+ renderItem={item => {
+ const note = item.item
+ let date = new Date(note.date)
+ const ms = ["Sty", "Lut", "Mar", "Kwi", "Maj", "Cze", "Lip", "Sie", "Wrz", "Paz", "Lis", "Gru"]
+ date = `${date.toISOString().substr(8, 2)} ${ms[date.getMonth()]}`
+ return (
+ <TouchableOpacity onLongPress={() =>
+ Alert.alert("Delete?", "There's no way back", [
+ {
+ text: "Cancel",
+ style: "cancel"
+ },
+ {
+ text: "OK",
+ onPress: () => deleteItem(note, this.setNotes)
+ }
+ ])
+ }
+ onPress={() => this.props.navigation.navigate("editNote", { note })
+ }
+ >
+ <View key={item.index} style={[styles.note, { backgroundColor: note.color }]}>
+ <View><Text style={[styles.category, { color: note.color, fontSize: this.state.font }]}>{note.category}</Text></View>
+ <View><Text style={[styles.date, { fontSize: this.state.font }]}>{date}</Text></View>
+ <View style={{ flex: 1 }}><Text style={[styles.title, { fontSize: this.state.font }]}>{note.title}</Text></View>
+ <View style={{ flex: 1 }}><Text style={[styles.body, { flexWrap: "wrap", fontSize: this.state.font }]}>{note.body}</Text></View>
+ </View>
+ </TouchableOpacity>
+ )
+ }}
+ keyExtractor={(_, i) => i.toString()}
+ contentContainerStyle={styles.list}
+ style={styles.list}
+ numColumns={2}
+ />
+ </View>
+ </View>
+ )
+ }
+}
+
+async function deleteItem(note, setNotes) {
+ let keyList = JSON.parse(await SecureStore.getItemAsync('notesKeys'))
+ await SecureStore.deleteItemAsync(note.key.toString())
+ keyList = keyList.filter(n => n !== note.key)
+ await SecureStore.setItemAsync('notesKeys', JSON.stringify(keyList))
+
+ getNotes(setNotes)
+}
+
+async function getNotes(setNotes) {
+ let notesKeys = await SecureStore.getItemAsync('notesKeys')
+ if (!notesKeys) notesKeys = []; else notesKeys = JSON.parse(notesKeys);
+ const notes = [];
+ for (const key of notesKeys) {
+ notes.push(JSON.parse(await SecureStore.getItemAsync(key.toString())))
+ }
+ setNotes(notes);
+}
+
+const styles = StyleSheet.create({
+ cont: {
+ flex: 1,
+ flexDirection: "column",
+ backgroundColor: "black",
+ },
+ note: {
+ width: 160,
+ height: 160,
+ backgroundColor: "red",
+ borderRadius: 10,
+ padding: 10,
+ marginTop: 30,
+ marginLeft: 30,
+ },
+ list: {
+ // height: 680,
+ },
+ btn: {
+ // borderColor: "red",
+ borderWidth: 3,
+ textAlign: "center",
+ flex: 0,
+ },
+ ico: {
+ width: 200,
+ height: 200,
+ },
+ input: {
+ fontSize: 25,
+ alignSelf: "center",
+ textAlign: "center",
+ width: "80%",
+ backgroundColor: "darkgrey",
+ borderRadius: 8,
+ margin: 10,
+ height: 60,
+ },
+ category: {
+ backgroundColor: "black",
+ // width: "fit-content",
+ margin: 10,
+ padding: 5,
+ borderRadius: 8,
+ alignSelf: "flex-start",
+ },
+ date: {
+ fontSize: 18,
+ color: "#FFFFFF",
+ textAlign: "right",
+ },
+ title: {
+ fontSize: 25,
+ fontWeight: "bold",
+ color: "#FFFFFF"
+ },
+ body: {
+ fontSize: 25,
+ color: "#FFFFFF"
+ },
+ txt: {
+ fontSize: 25,
+ fontWeight: "bold",
+ color: "#FFFFFF"
+ },
+})
+
diff --git a/components/Options.js b/components/Options.js
new file mode 100644
index 0000000..fd0c21c
--- /dev/null
+++ b/components/Options.js
@@ -0,0 +1,68 @@
+import * as React from 'react';
+import { SafeAreaView, TextInput, StyleSheet, Text, TouchableOpacity } from 'react-native';
+import * as SecureStore from 'expo-secure-store';
+
+let a = true
+export default function CategoryView(props) {
+ let [font, setFont] = React.useState(0)
+
+ async function setFontSS(f) {
+ setFont(f);
+ await SecureStore.setItemAsync('font', f.toString())
+ }
+
+ React.useEffect(() => getFont(setFont), [])
+ if (a) {
+ props.navigation.addListener('focus', () => getFont(setFont))
+ a = false
+ }
+
+ return (
+ <SafeAreaView style={styles.cont}>
+ <Text style={styles.txt}>Selected font: {font}</Text>
+ <TouchableOpacity onPress={() => setFontSS(12)}><Text style={[styles.txt, styles.btn]}>Font 12</Text></TouchableOpacity>
+ <TouchableOpacity onPress={() => setFontSS(19)}><Text style={[styles.txt, styles.btn]}>Font 19</Text></TouchableOpacity >
+ <TouchableOpacity onPress={() => setFontSS(26)}><Text style={[styles.txt, styles.btn]}>Font 26</Text></TouchableOpacity >
+ </SafeAreaView >
+ )
+}
+export async function getFont(setFont) {
+ let font = await SecureStore.getItemAsync('font')
+ if (!font) { font = 22; await SecureStore.setItemAsync('font', '22'); } else font = JSON.parse(font);
+ setFont(parseInt(font));
+}
+
+const styles = StyleSheet.create({
+ cont: {
+ flex: 1,
+ backgroundColor: "black",
+ padding: 20,
+ alignItems: "center"
+ },
+ ico: {
+ width: 200,
+ height: 200,
+ },
+ txt: {
+ fontSize: 30,
+ fontWeight: "bold",
+ color: "#FFFFFF"
+ },
+ btn: {
+ textAlign: "center",
+ borderColor: "pink",
+ borderWidth: 5,
+ margin: 10,
+ padding: 10,
+ },
+ input: {
+ height: 40,
+ width: "100%",
+ margin: 12,
+ borderWidth: 1,
+ padding: 10,
+ color: "#FFFFFF",
+ }
+})
+
+