diff --git a/apps/web/src/common/index.js b/apps/web/src/common/index.js
index fa54d861d..8f6d88a1d 100644
--- a/apps/web/src/common/index.js
+++ b/apps/web/src/common/index.js
@@ -4,3 +4,7 @@ import events from "events";
export const db = new Database(StorageInterface);
export const ev = new events.EventEmitter();
+
+export function sendNewNoteEvent() {
+ ev.emit("onNewNote");
+}
diff --git a/apps/web/src/components/list-item/index.js b/apps/web/src/components/list-item/index.js
new file mode 100644
index 000000000..fce5e1384
--- /dev/null
+++ b/apps/web/src/components/list-item/index.js
@@ -0,0 +1,73 @@
+import React from "react";
+import { Flex, Box, Text } from "rebass";
+import * as Icon from "react-feather";
+import { ButtonPressedStyle } from "../../theme";
+import Dropdown, { DropdownTrigger, DropdownContent } from "../dropdown";
+import Menu from "../menu";
+
+const ListItem = props => (
+ {
+ if (props.onClick) {
+ props.onClick();
+ }
+ e.stopPropagation();
+ }}
+ alignItems="center"
+ justifyContent="space-between"
+ py={1}
+ sx={{
+ borderRadius: "default",
+ marginBottom: 2,
+ borderBottom: "1px solid",
+ borderBottomColor: "navbg",
+ cursor: "default",
+ ...ButtonPressedStyle
+ }}
+ >
+
+
+
+ {props.title}
+
+
+
+ {props.body}
+
+ {props.subBody && props.subBody}
+
+ {props.info}
+
+
+ (props.dropdownRefs[props.index] = ref)}
+ >
+
+
+
+
+
+
+
+
+);
+
+export default ListItem;
diff --git a/apps/web/src/components/note/index.js b/apps/web/src/components/note/index.js
new file mode 100644
index 000000000..79856e9a9
--- /dev/null
+++ b/apps/web/src/components/note/index.js
@@ -0,0 +1,49 @@
+import React from "react";
+import * as Icon from "react-feather";
+import TimeAgo from "timeago-react";
+import { db, ev } from "../../common";
+import { showSnack } from "../snackbar";
+import ListItem from "../list-item";
+
+const dropdownRefs = [];
+const menuItems = [
+ { title: "Favorite", icon: Icon.Heart },
+ { title: "Share", icon: Icon.Share2 },
+ {
+ title: "Delete",
+ icon: Icon.Trash,
+ color: "red",
+ onClick: note => {
+ ev.emit("onClearNote", note.dateCreated);
+ db.deleteNotes([note]).then(
+ //TODO implement undo
+ () => {
+ showSnack("Note deleted!", Icon.Check);
+ ev.emit("refreshNotes");
+ }
+ );
+ }
+ }
+];
+
+function sendOpenNoteEvent(note) {
+ ev.emit("onOpenNote", note);
+}
+
+const Note = ({ item, index }) => {
+ const note = item;
+ return (
+ }
+ menuData={note}
+ menuItems={menuItems}
+ dropdownRefs={dropdownRefs}
+ />
+ );
+};
+
+export default Note;
diff --git a/apps/web/src/components/notebook/index.js b/apps/web/src/components/notebook/index.js
new file mode 100644
index 000000000..0cb64c2bb
--- /dev/null
+++ b/apps/web/src/components/notebook/index.js
@@ -0,0 +1,64 @@
+import React from "react";
+import { Flex, Text } from "rebass";
+import * as Icon from "react-feather";
+import ListItem from "../list-item";
+
+const dropdownRefs = [];
+const menuItems = [
+ { title: "Favorite", icon: Icon.Heart },
+ { title: "Share", icon: Icon.Share2 },
+ {
+ title: "Delete",
+ icon: Icon.Trash,
+ color: "red"
+ }
+];
+const Notebook = ({ item, index, onClick, onTopicClick }) => {
+ const notebook = item;
+ return (
+
+ {notebook.topics.slice(1, 4).map(topic => (
+ {
+ onTopicClick(notebook, topic);
+ e.stopPropagation();
+ }}
+ key={topic.dateCreated + topic.title}
+ bg="accent"
+ px={1}
+ py={1}
+ sx={{
+ marginRight: 1,
+ borderRadius: "default",
+ color: "fontSecondary"
+ }}
+ >
+
+ {topic.title}
+
+
+ ))}
+
+ }
+ info={
+
+ {new Date(notebook.dateCreated).toDateString().substring(4)}
+
+ {" • " + notebook.totalNotes} Notes
+
+
+ }
+ dropdownRefs={dropdownRefs}
+ index={index}
+ menuData={notebook}
+ menuItems={menuItems}
+ />
+ );
+};
+
+export default Notebook;
diff --git a/apps/web/src/components/search/index.js b/apps/web/src/components/search/index.js
index 8ca89029d..38b4fd731 100644
--- a/apps/web/src/components/search/index.js
+++ b/apps/web/src/components/search/index.js
@@ -2,7 +2,7 @@ import React from "react";
import { Flex, Box } from "rebass";
import { Input } from "@rebass/forms";
import * as Icon from "react-feather";
-import theme, { SHADOW } from "../../theme";
+import theme from "../../theme";
import "./search.css";
const Search = props => (
{
+ const topic = item;
+ return (
+
+
+ {topic.totalNotes} Notes
+
+
+ }
+ index={index}
+ dropdownRefs={dropdownRefs}
+ menuData={topic}
+ menuItems={menuItems}
+ />
+ );
+};
+
+export default Topic;
diff --git a/apps/web/src/navigation/index.js b/apps/web/src/navigation/index.js
index ec24561ed..e5ed99da6 100644
--- a/apps/web/src/navigation/index.js
+++ b/apps/web/src/navigation/index.js
@@ -1,4 +1,4 @@
-import React from "react";
+import React, { useState } from "react";
import ReactDOM from "react-dom";
import Home from "../views/Home";
import Notebooks from "../views/Notebooks";
@@ -79,10 +79,13 @@ export function goBack(root) {
}
function ThemedComponent(props) {
+ const [title, setTitle] = useState(props.route.title);
return (
- {props.route.title}
- {props.route.component && }
+ {title}
+ {props.route.component && (
+
+ )}
);
}
diff --git a/apps/web/src/views/Home.js b/apps/web/src/views/Home.js
index c3f32bc6b..a26cf2b29 100644
--- a/apps/web/src/views/Home.js
+++ b/apps/web/src/views/Home.js
@@ -1,56 +1,22 @@
import React, { useEffect, useState } from "react";
-import { Flex, Box, Text } from "rebass";
+import { Flex, Text } from "rebass";
import * as Icon from "react-feather";
-import { ButtonPressedStyle } from "../theme";
-import Dropdown, {
- DropdownTrigger,
- DropdownContent
-} from "../components/dropdown";
-import TimeAgo from "timeago-react";
-import { db, ev } from "../common";
+import { db, ev, sendNewNoteEvent } from "../common";
import { Virtuoso as List } from "react-virtuoso";
-import { showSnack } from "../components/snackbar";
-import Menu from "../components/menu";
import Button from "../components/button";
import Search from "../components/search";
+import Note from "../components/note";
-const dropdownRefs = [];
-const menuItems = [
- { title: "Favorite", icon: Icon.Heart },
- { title: "Share", icon: Icon.Share2 },
- {
- title: "Delete",
- icon: Icon.Trash,
- color: "red",
- onClick: note => {
- ev.emit("onClearNote", note.dateCreated);
- db.deleteNotes([note]).then(
- //TODO implement undo
- () => {
- showSnack("Note deleted!", Icon.Check);
- //TODO very crude but works.
- Home.onRefresh();
- }
- );
- }
- }
-];
-
-function sendNewNoteEvent() {
- ev.emit("onNewNote");
-}
-function sendOpenNoteEvent(note) {
- ev.emit("onOpenNote", note);
-}
function Home() {
const [notes, setNotes] = useState([]);
useEffect(() => {
- Home.onRefresh = () => {
+ function onRefreshNotes() {
setNotes(db.getNotes());
- };
- Home.onRefresh();
+ }
+ onRefreshNotes();
+ ev.addListener("refreshNotes", onRefreshNotes);
return () => {
- Home.onRefresh = undefined;
+ ev.removeListener("refreshNotes", onRefreshNotes);
};
}, []);
return (
@@ -66,62 +32,7 @@ function Home() {
overflowX: "hidden"
}}
totalCount={notes.length}
- item={index => {
- const note = notes[index];
- return (
- {
- sendOpenNoteEvent(note);
- e.stopPropagation();
- }}
- py={3}
- sx={{
- borderRadius: "default",
- marginBottom: 2,
- borderBottom: "1px solid",
- borderBottomColor: "navbg",
- cursor: "default",
- ...ButtonPressedStyle
- }}
- >
-
-
- {note.title}
-
- (dropdownRefs[index] = ref)}
- >
-
-
-
-
-
-
-
-
-
- {note.headline}
-
-
-
-
-
- );
- }}
+ item={index => }
/>