Added bookmark support

This commit is contained in:
Bastian Meissner 2020-05-21 21:39:17 +02:00
parent b7fd770c27
commit a82bdc1620
7 changed files with 264 additions and 36 deletions

98
data/bookmarks.json Normal file
View file

@ -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"
}
]
}
]
}

64
data/search.json Normal file
View file

@ -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"
}
]
}

25
data/themes.json Normal file
View file

@ -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"
}
]
}

View file

@ -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]);

View file

@ -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 = () => (
function handleResponse(response) {
if (response.ok) {
return response.json();
}
throw new Error('Failed to load app data.');
}
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 (
<ListContainer>
<Headline>Bookmarks</Headline>
<Headline>Applications</Headline>
<RefreshButton onClick={fetchBookmarkData}>refresh</RefreshButton>
<ItemList>
{bookmarkData.groups.map(({ name, items }) => (
<Item key={name}>
{error && <ErrorMessage>{error}</ErrorMessage>}
{groups.map((group, idx) => {
return (
<Item key={[group.name, idx].join('')}>
<BookmarkGroup>
<Group>{name}</Group>
{items.map(({ url, name: linkName }) => (
<Group>{group.name}</Group>
{group.items.map(({ url, name: linkName }) => (
<Bookmark key={linkName} href={url}>
{linkName}
</Bookmark>
))}
</BookmarkGroup>
</Item>
))}
);
})}
</ItemList>
</ListContainer>
);
};
export default bookmarkList;
export default BookmarkList;

View file

@ -1,7 +1,7 @@
{
"apps": [
{
"name": "PiHole",
"name": "my pi hole",
"displayURL": "example.com",
"URL": "https://example.com",
"icon": "vpn_lock"

View file

@ -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 &&