diff --git a/data/bookmarks.json b/data/bookmarks.json
new file mode 100644
index 0000000..ac8e00c
--- /dev/null
+++ b/data/bookmarks.json
@@ -0,0 +1,98 @@
+{
+ "groups": [
+ {
+ "name": "Wikis",
+ "items": [
+ {
+ "name": "Wikipedia",
+ "url": "https://en.wikipedia.org/"
+ },
+ {
+ "name": "Arch Linux Wiki",
+ "url": "https://archlinux.org/"
+ }
+ ]
+ },
+ {
+ "name": "Dev",
+ "items": [
+ {
+ "name": "Codepen",
+ "url": "https://codepen.io/"
+ },
+ {
+ "name": "JSFiddle",
+ "url": "https://jsfiddle.net/"
+ },
+ {
+ "name": "Pastebin",
+ "url": "https://pastebin.com/"
+ }
+ ]
+ },
+ {
+ "name": "Media",
+ "items": [
+ {
+ "name": "Soundcloud",
+ "url": "https://soundcloud.com"
+ },
+ {
+ "name": "YouTube",
+ "url": "https://youtube.com"
+ },
+ {
+ "name": "Twitch",
+ "url": "https://twitch.tv"
+ }
+ ]
+ },
+ {
+ "name": "Social Networks",
+ "items": [
+ {
+ "name": "Facebook",
+ "url": "https://facebook.com"
+ },
+ {
+ "name": "Twitter",
+ "url": "https://twitter.com"
+ },
+ {
+ "name": "Instagram",
+ "url": "https://instagram.com"
+ }
+ ]
+ },
+ {
+ "name": "Imageboards",
+ "items": [
+ {
+ "name": "Reddit",
+ "url": "https://reddit.com"
+ },
+ {
+ "name": "4chan",
+ "url": "https://4chan.org"
+ }
+ ]
+ },
+ {
+ "name": "Tech",
+ "items": [
+ {
+ "name": "Hackernoon",
+ "url": "https://hackernoon.com"
+ },
+ {
+ "name": "The Verge",
+ "url": "https://theverge.com"
+ },
+ {
+ "name": "Hackernews",
+ "url": "https://news.ycombinator.com"
+ }
+ ]
+ }
+ ]
+}
diff --git a/data/search.json b/data/search.json
new file mode 100644
index 0000000..61a82eb
--- /dev/null
+++ b/data/search.json
@@ -0,0 +1,64 @@
+{
+ "providers": [
+ {
+ "name": "Allmusic",
+ "url": "https://www.allmusic.com/search/all/",
+ "prefix": "/a"
+ },
+ {
+ "name": "Discogs",
+ "url": "https://www.discogs.com/search/?q=",
+ "prefix": "/di"
+ },
+ {
+ "name": "Duck Duck Go",
+ "url": "https://duckduckgo.com/?q=",
+ "prefix": "/d"
+ },
+ {
+ "name": "iMDB",
+ "url": "https://www.imdb.com/find?q=",
+ "prefix": "/i"
+ },
+ {
+ "name": "TheMovieDB",
+ "url": "https://www.themoviedb.org/search?query=",
+ "prefix": "/m"
+ },
+ {
+ "name": "Reddit",
+ "url": "https://www.reddit.com/search?q=",
+ "prefix": "/r"
+ },
+ {
+ "name": "Qwant",
+ "url": "https://www.qwant.com/?q=",
+ "prefix": "/q"
+ },
+ {
+ "name": "Soundcloud",
+ "url": "https://soundcloud.com/search?q=",
+ "prefix": "/so"
+ },
+ {
+ "name": "Spotify",
+ "url": "https://open.spotify.com/search/results/",
+ "prefix": "/s"
+ },
+ {
+ "name": "TheTVDB",
+ "url": "https://www.thetvdb.com/search?q=",
+ "prefix": "/tv"
+ },
+ {
+ "name": "Trakt",
+ "url": "https://trakt.tv/search?query=",
+ "prefix": "/t"
+ },
+ {
+ "name": "YouTube",
+ "url": "https://youtube.com/results?search_query=",
+ "prefix": "/yt"
+ }
+ ]
+}
diff --git a/data/themes.json b/data/themes.json
new file mode 100644
index 0000000..10a5543
--- /dev/null
+++ b/data/themes.json
@@ -0,0 +1,25 @@
+{
+ "themes": [
+ {
+ "label": "Classic",
+ "value": 0,
+ "mainColor": "#000000",
+ "accentColor": "#1e272e",
+ "backgroundColor": "#ffffff"
+ },
+ {
+ "label": "Dark",
+ "value": 1,
+ "mainColor": "#ffffff",
+ "accentColor": "#999999",
+ "backgroundColor": "#000000"
+ },
+ {
+ "label": "Raw",
+ "value": 2,
+ "mainColor": "",
+ "accentColor": "",
+ "backgroundColor": "#ffffff"
+ }
+ ]
+}
diff --git a/src/components/appList.js b/src/components/appList.js
index 2675ef1..25b0763 100644
--- a/src/components/appList.js
+++ b/src/components/appList.js
@@ -4,7 +4,7 @@ import styled from 'styled-components';
import selectedTheme from './themeManager';
-import { Headline, ListContainer, ItemList, Item, Button } from './elements';
+import { Headline, ListContainer, ItemList, Item, RefreshButton, ErrorMessage } from './elements';
const IconContainer = styled.div`
margin-right: 0.5vh;
@@ -41,16 +41,6 @@ const App = styled.div`
padding: 1rem;
`;
-const ErrorMessage = styled.p`
- color: red;
-`;
-
-const RefreshButton = styled(Button)`
- display: relative;
- top: 0;
- float: right;
-`;
-
function handleResponse(response) {
if (response.ok) {
return response.json();
@@ -72,6 +62,11 @@ function useAppData() {
setAppData({ apps: [], error: error.message });
});
}, []);
+
+ useEffect(() => {
+ console.log(appData)
+ }, [appData]);
+
useEffect(() => {
fetchAppData();
}, [fetchAppData]);
diff --git a/src/components/bookmarkList.js b/src/components/bookmarkList.js
index 3544b74..7a9e518 100644
--- a/src/components/bookmarkList.js
+++ b/src/components/bookmarkList.js
@@ -1,10 +1,8 @@
-import React from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import styled from 'styled-components';
-import bookmarkData from './data/bookmarks.json';
-
import selectedTheme from './themeManager';
-import { Headline, ListContainer, ItemList, Item } from './elements';
+import { Headline, ListContainer, ItemList, Item, RefreshButton, ErrorMessage } from './elements';
const Group = styled.h4`
font-family: Roboto, sans-serif;
@@ -30,24 +28,62 @@ const Bookmark = styled.a`
font-size: 14px;
`;
-const bookmarkList = () => (
-
- Bookmarks
-
- {bookmarkData.groups.map(({ name, items }) => (
- -
-
- {name}
- {items.map(({ url, name: linkName }) => (
-
- {linkName}
-
- ))}
-
-
- ))}
-
-
-);
+function handleResponse(response) {
+ if (response.ok) {
+ return response.json();
+ }
+ throw new Error('Failed to load app data.');
+}
-export default bookmarkList;
+const useBookmarkData = () => {
+ const [bookmarkData, setBookmarkData] = useState({ groups: [], error: false });
+ const fetchBookmarkData = useCallback(() => {
+ (process.env.NODE_ENV === 'production'
+ ? fetch('/bookmarks.json').then(handleResponse)
+ : import('./data/bookmarks.json')
+ )
+ .then(jsonResponse => {
+ setBookmarkData({ ...jsonResponse, error: false });
+ })
+ .catch(error => {
+ setBookmarkData({ groups: [], error: error.message });
+ });
+ }, []);
+
+ useEffect(() => {
+ fetchBookmarkData();
+ }, [fetchBookmarkData]);
+ return { bookmarkData, fetchBookmarkData };
+}
+
+const BookmarkList = () => {
+ const {
+ bookmarkData: { groups, error },
+ fetchBookmarkData
+ } = useBookmarkData();
+ return (
+
+ Applications
+ refresh
+
+ {error && {error}}
+ {groups.map((group, idx) => {
+ return (
+ -
+
+ {group.name}
+ {group.items.map(({ url, name: linkName }) => (
+
+ {linkName}
+
+ ))}
+
+
+ );
+ })}
+
+
+ );
+};
+
+export default BookmarkList;
\ No newline at end of file
diff --git a/src/components/data/apps.json b/src/components/data/apps.json
index cce34d9..d0c3fdc 100644
--- a/src/components/data/apps.json
+++ b/src/components/data/apps.json
@@ -1,7 +1,7 @@
{
"apps": [
{
- "name": "PiHole",
+ "name": "my pi hole",
"displayURL": "example.com",
"URL": "https://example.com",
"icon": "vpn_lock"
diff --git a/src/components/elements.js b/src/components/elements.js
index 9b1d3a3..57ff3fd 100644
--- a/src/components/elements.js
+++ b/src/components/elements.js
@@ -51,6 +51,16 @@ const StyledButton = styled.button`
background: none;
`;
+export const RefreshButton = styled(Button)`
+ display: relative;
+ top: 0;
+ float: right;
+`;
+
+export const ErrorMessage = styled.p`
+ color: red;
+`;
+
export const IconButton = props => {
if (
props.icon &&