build: initial commit with React

This commit is contained in:
Resi Respati 2017-12-19 19:26:16 +07:00
parent 27ad8f9bb4
commit ff0140134f
30 changed files with 7993 additions and 0 deletions

9
.editorconfig Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

18
.eslintrc.js Normal file
View File

@ -0,0 +1,18 @@
module.exports = {
root: true,
extends: 'airbnb',
parser: 'babel-eslint',
env: {
browser: true
},
globals: {
shallow: false,
render: false,
mount: false
},
plugins: ['react', 'prefer-object-spread', 'compat'],
rules: {
'max-len': ['error', 120],
'react/jsx-filename-extension': [1, { 'extensions': ['.js'] }]
}
};

22
.gitattributes vendored Normal file
View File

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text eol=lf
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

15
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.renderWhitespace": "boundary",
"files.encoding": "utf8",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"editor.rulers": [
80,
120
],
"search.exclude": {
"build/**": true,
}
}

23
README.md Normal file
View File

@ -0,0 +1,23 @@
# tildetv-frontend
> A web player for all videos shared within tilde.town. Sit back and relax.
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
## Build Setup
A nodejs >= 8.0.0 setup with [yarn](https://yarnpkg.com/) is recommended.
``` bash
# install dependencies
yarn
# starts the development server
yarn start
# bundles the app into static files for production
yarn build
# starts the test runner
yarn test
```

40
package.json Normal file
View File

@ -0,0 +1,40 @@
{
"name": "tildetv-frontend",
"version": "0.1.0",
"private": true,
"homepage": "https://tilde.town/~resir014/tildetv",
"dependencies": {
"axios": "^0.17.1",
"normalize.css": "^7.0.0",
"prop-types": "^15.6.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-paginate": "^5.0.0",
"react-router-dom": "^4.2.2",
"react-scripts": "1.0.17",
"styled-components": "^2.3.0"
},
"scripts": {
"build": "react-scripts build",
"commit": "git-cz",
"eject": "react-scripts eject",
"start": "react-scripts start",
"test": "react-scripts test --env=jsdom"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"devDependencies": {
"commitizen": "^2.9.6",
"cz-conventional-changelog": "^2.1.0",
"eslint": "^4.13.1",
"eslint-config-airbnb": "^16.1.0",
"eslint-plugin-compat": "^2.1.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-prefer-object-spread": "^1.2.1",
"eslint-plugin-react": "^7.5.1"
}
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

40
public/index.html Normal file
View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

15
public/manifest.json Normal file
View File

@ -0,0 +1,15 @@
{
"short_name": "tildetv",
"name": "tildetv",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@ -0,0 +1,53 @@
[
{
"contentWarnings": [
"Trains"
],
"description": "One of my favourite videos, a relaxing minute by minute train journey from Bergen to Oslo",
"title": "BergensBanen minutt for minutt HD (Full video)",
"addedtime": 1492970809,
"tags": [
"SlowTv",
"Train",
"Norway"
],
"youtubelink": "https://www.youtube.com/watch?v=z7VYVjR_nwE",
"id": {
"v": [
"z7VYVjR_nwE"
]
},
"user": "karlen"
},
{
"contentWarnings": [],
"description": "A must watch even if you don't like sports. Jon Bois from SB Nation uses some neat statistics to figure out if baseballer Barry Bonds would still do well, even without carrying a bat.",
"title": "What if Barry Bonds had played without a baseball bat? | Chart Party",
"addedtime": 1492256083,
"tags": [
"sports",
"statistics"
],
"youtubelink": "https://www.youtube.com/watch?v=JwMfT2cZGHg",
"id": {
"v": [
"JwMfT2cZGHg"
]
},
"user": "resir014"
},
{
"contentWarnings": [],
"description": "A parody talk researching the turing-completeness of PowerPoint.",
"title": "On The Turing Completeness of PowerPoint (SIGBOVIK)",
"addedtime": 14924141943,
"tags": [],
"youtubelink": "https://www.youtube.com/watch?v=uNjxe8ShM-8",
"id": {
"v": [
"uNjxe8ShM-8"
]
},
"user": "resir014"
}
]

22
src/Root.js Normal file
View File

@ -0,0 +1,22 @@
import * as React from 'react';
import { Route, Switch } from 'react-router-dom';
import AppContainer from './containers/App';
import Home from './pages/Home';
import Videos from './pages/Videos';
import Howto from './pages/Howto';
import Playground from './pages/Playground';
const Root = () => (
<AppContainer>
<Switch>
<Route path="/" exact component={Home} />
<Route path="/videos" component={Videos} />
<Route path="/howto" component={Howto} />
{process.env.NODE_ENV !== 'production' && <Route path="/playground" component={Playground} />}
</Switch>
</AppContainer>
);
export default Root;

12
src/Root.test.js Normal file
View File

@ -0,0 +1,12 @@
/* eslint-env node, jest */
import React from 'react';
import ReactDOM from 'react-dom';
import Root from './Root';
describe('Root', () => {
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<Root />, div);
});
});

View File

@ -0,0 +1,33 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import styled from 'styled-components';
const Wrapper = styled.section`
padding: 1rem;
margin-bottom: 1rem;
font-size: .8rem;
line-height: 1.4;
background-color: var(--code-background-color);
border-radius: .25rem;
pre {
margin-bottom: 0;
overflow-x: auto;
}
`;
/**
* Wrap a code block inside a React component.
*/
const CodeBlock = ({ code }) => (
<Wrapper>
<pre>{code}</pre>
</Wrapper>
);
CodeBlock.propTypes = {
/** A template string containing the code we want to include. */
code: PropTypes.string.isRequired,
};
export default CodeBlock;

View File

@ -0,0 +1,31 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import styled from 'styled-components';
/**
* Wrap content inside a container to wrap them inside a fixed-width or fluid container.
*/
const Container = ({ children, className }) => (
<div className={className}>
{children}
</div>
);
Container.propTypes = {
/** Child nodes of the container. */
children: PropTypes.node.isRequired,
/** Any additional classes to put inside the container. */
className: PropTypes.string,
};
Container.defaultProps = {
className: null,
};
export default styled(Container)`
max-width: ${props => (props.fluid ? '100%' : '48em')};
margin-left: auto;
margin-right: auto;
padding-left: 1rem;
padding-right: 1rem;
`;

7
src/components/Footer.js Normal file
View File

@ -0,0 +1,7 @@
import * as React from 'react';
const Footer = () => (
<div>Footer</div>
);
export default Footer;

72
src/components/Header.js Normal file
View File

@ -0,0 +1,72 @@
import * as React from 'react';
import { NavLink } from 'react-router-dom';
import styled from 'styled-components';
const SiteHeader = styled.header`
padding: 1rem 0;
margin-bottom: 2rem;
text-align: center;
`;
const SiteNavigation = styled.nav`
margin: 1.5rem 0;
a,
a:hover,
a:focus {
text-decoration: none;
}
`;
const SiteBrand = styled.h1`
margin-top: 0;
margin-bottom: 0;
font-weight: 300;
font-size: 2.5rem;
span {
font-weight: 600;
}
small {
font-size: 1rem;
}
`;
const SiteTagline = styled.span`
font-size: 1.25rem;
font-weight: 300;
`;
const SiteNavigationLink = styled(NavLink)`
display: inline-block;
margin: 0 1rem;
&.router-link--active {
color: inherit;
}
`;
const Home = () => (
<SiteHeader>
<SiteBrand>tilde<span>tv</span></SiteBrand>
<SiteTagline>sit back and relax</SiteTagline>
<SiteNavigation>
<SiteNavigationLink exact to="/" className="router-link" activeClassName="router-link--active">
about
</SiteNavigationLink>
<SiteNavigationLink to="/videos" className="router-link" activeClassName="router-link--active">
{'this week\'s playlist'}
</SiteNavigationLink>
<SiteNavigationLink to="/howto" className="router-link" activeClassName="router-link--active">
add videos
</SiteNavigationLink>
{process.env.NODE_ENV !== 'production' &&
<SiteNavigationLink to="/playground" className="router-link" activeClassName="router-link--active">
component playground
</SiteNavigationLink>}
</SiteNavigation>
</SiteHeader>
);
export default Home;

21
src/components/Video.js Normal file
View File

@ -0,0 +1,21 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
const Video = ({ video }) => (
<div>{JSON.stringify(video)}</div>
);
Video.propTypes = {
video: PropTypes.shape({
title: PropTypes.string,
description: PropTypes.string,
user: PropTypes.string,
addedtime: PropTypes.number,
tags: PropTypes.arrayOf(PropTypes.string),
youtubelink: PropTypes.string,
id: PropTypes.object,
contentWarnings: PropTypes.arrayOf(PropTypes.string),
}).isRequired,
};
export default Video;

22
src/containers/App.js Normal file
View File

@ -0,0 +1,22 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import styled from 'styled-components';
import Header from '../components/Header';
const Wrapper = styled.div`
height: 100%;
`;
const AppContainer = ({ children }) => (
<Wrapper>
<Header />
{children}
</Wrapper>
);
AppContainer.propTypes = {
children: PropTypes.node.isRequired,
};
export default AppContainer;

28
src/containers/Page.js Normal file
View File

@ -0,0 +1,28 @@
import * as React from 'react';
import * as PropTypes from 'prop-types';
import styled from 'styled-components';
import Container from '../components/Container';
const Wrapper = styled.main`
margin: 2rem 0;
`;
const PageContainer = ({ children, isFluid }) => (
<Wrapper role="main">
<Container fluid={isFluid}>
<article>{children}</article>
</Container>
</Wrapper>
);
PageContainer.propTypes = {
children: PropTypes.node.isRequired,
isFluid: PropTypes.bool,
};
PageContainer.defaultProps = {
isFluid: false,
};
export default PageContainer;

70
src/containers/Videos.js Normal file
View File

@ -0,0 +1,70 @@
import * as React from 'react';
import * as axios from 'axios';
// import styled from 'styled-components';
import Video from '../components/Video';
class VideosContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
fetched: false,
videos: [],
errors: [],
};
}
componentWillMount() {
this.fetchVideos();
}
fetchVideos() {
const baseUrl = process.env.NODE_ENV !== 'production'
? '/sample-api'
: '/~karlen/tv';
const api = axios.create({
baseURL: baseUrl,
timeout: 10000,
headers: {
Accept: 'application/json',
'Cache-Control': 'no-cache',
},
});
api.get('/videos.json').then((res) => {
this.setState({
fetched: true,
videos: res.data,
});
}).catch((e) => {
this.setState({
fetched: true,
errors: e,
});
});
}
renderLoading = () => (
<div>Loading...</div>
);
renderVideos = videos => (
<div>
<h2>we have {videos.length} video(s) for you this week</h2>
{videos.map(video => <Video key={video.id.v[0]} video={video} />)}
</div>
);
render() {
if (this.state.fetched) {
return this.state.errors.length === 0
? this.renderVideos(this.state.videos)
: null;
}
return this.renderLoading();
}
}
export default VideosContainer;

15
src/index.js Normal file
View File

@ -0,0 +1,15 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import 'normalize.css';
import './styles/index.css';
import Root from './Root';
const wrapped = (
<BrowserRouter>
<Root />
</BrowserRouter>
);
ReactDOM.render(wrapped, document.getElementById('root'));

7
src/logo.svg Normal file
View File

@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
<g fill="#61DAFB">
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
<circle cx="420.9" cy="296.5" r="45.7"/>
<path d="M520.5 78.1z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

32
src/pages/Home.js Normal file
View File

@ -0,0 +1,32 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
import Page from '../containers/Page';
const Home = () => (
<Page>
<h1>welcome to tildetv</h1>
<p>
tildetv is an alternative way to enjoy visual media on the internet. it&apos;s a playlist of YouTube videos{' '}
discovered and curated by{' '}
<a href="https://tilde.town" target="_blank" rel="noopener noreferrer">
tilde.town members
</a>{' '}
from a variety of different categories across the site, and are available here for everyone&apos;s viewing{' '}
pleasure.
</p>
<h2>features</h2>
<ul>
<li>simple, intuitive <Link href="/videos" to="/videos">web viewer</Link> (with tags &amp; content warnings)</li>
<li><Link href="/howto" to="/howto">add videos to the playlist</Link> using a simple command line</li>
<li>
<a href="https://tilde.town/~karlen/tv/videos.json" target="_blank" rel="noopener noreferrer">
JSON datadump
</a>, for ~town members who want to develop their own, in-console client
</li>
<li>videos are reset every week, so you&apos;re bound to see something fresh!</li>
</ul>
</Page>
);
export default Home;

34
src/pages/Howto.js Normal file
View File

@ -0,0 +1,34 @@
import * as React from 'react';
import Container from '../components/Container';
import CodeBlock from '../components/CodeBlock';
const cli = `$ ~karlen/tv/addtotv -h
Usage: addtotv [options] arg
Options:
-h, --help show this help message and exit
-l LINK, --link=LINK URL to youtube video quoted. e.g. -l
"https://www.youtube.com/watch?v=z7VYVjR_nwE"
-t TAGS, --tags=TAGS Tags, comma separated and quoted. e.g. -t "Train, Ice,
cold"
-c CW, --contentwarning=CW
Content warning, comma separated and quoted. e.g. -c
"Doggo, pupper, Joyce"
-d DESC, --description=DESC
Description of the video, quoted. e.g. "A real
angerery pupper writing about pubs"`;
const Home = () => (
<Container>
<h1>adding stuff to tildetv</h1>
<p>
to add videos to tildetv you can use the command-line tool provided by{' '}
<a href="https://tilde.town/~karlen">~karlen</a>.
</p>
<CodeBlock code={cli} />
</Container>
);
export default Home;

11
src/pages/Playground.js Normal file
View File

@ -0,0 +1,11 @@
import * as React from 'react';
import Page from '../containers/Page';
const Playground = () => (
<Page>
<h1>component playground</h1>
<p>test your components here, y&apos;all.</p>
</Page>
);
export default Playground;

11
src/pages/Videos.js Normal file
View File

@ -0,0 +1,11 @@
import * as React from 'react';
import Page from '../containers/Page';
import VideosContainer from '../containers/Videos';
const Videos = () => (
<Page>
<VideosContainer />
</Page>
);
export default Videos;

191
src/styles/index.css Normal file
View File

@ -0,0 +1,191 @@
/* Variables
========================================================================== */
:root {
/*
* Colours based on the base16 styleguide
* https://chriskempson.github.io/base16/
*/
--base00-background: #181818;
--base01-background: #282828;
--base02-background: #383838;
--base03-background: #585858;
--base04-background: #b8b8b8;
--base05-background: #d8d8d8;
--base06-background: #e8e8e8;
--base07-background: #f8f8f8;
--base08-background: #ab4642;
--base09-background: #dc9656;
--base0A-background: #f7ca88;
--base0B-background: #a1b56c;
--base0C-background: #86c1b9;
--base0D-background: #7cafc2;
--base0E-background: #ba8baf;
--base0F-background: #a16946;
--base00: #181818;
--base01: #282828;
--base02: #383838;
--base03: #585858;
--base04: #b8b8b8;
--base05: #d8d8d8;
--base06: #e8e8e8;
--base07: #f8f8f8;
--base08: #ab4642;
--base09: #dc9656;
--base0A: #f7ca88;
--base0B: #a1b56c;
--base0C: #86c1b9;
--base0D: #7cafc2;
--base0E: #ba8baf;
--base0F: #a16946;
/* Base variables */
--root-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
--root-font-size: 16px;
--root-line-height: 1.35;
/* Typography */
--body-color: var(--base05);
--body-bg: var(--base00-background);
--heading-color: var(--base07);
--heading-line-height: 1.15;
--link-color: var(--base0E);
/* Other components */
--label-color: var(--base01-background);
/* Code */
--code-font-family: Consolas, "Liberation Mono", Menlo, Monaco, Courier New, monospace;
--code-color: #bf616a;
--code-background-color: var(--base01-background);
/* Content warnings */
--content-warning-label-background: var(--base08-background);
--content-warning-label-color: var(--base05);
}
/* Global resets
========================================================================== */
html {
height: 100%;
font-family: var(--root-font-family);
font-size: var(--root-font-size);
line-height: var(--root-line-height);
box-sizing: border-box;
}
* {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
background-color: var(--body-bg);
color: var(--body-color);
height: 100%;
}
a {
color: var(--link-color);
text-decoration: none;
}
a:hover,
a:focus {
text-decoration: underline;
}
a strong {
color: inherit;
}
img {
display: block;
max-width: 100%;
margin: 0 0 1rem;
}
/* Typography
========================================================================== */
h1, h2, h3, h4, h5, h6 {
margin-bottom: .5rem;
font-weight: 400;
line-height: var(--heading-line-height);
color: var(--base07);
text-rendering: optimizeLegibility;
}
h1 {
font-size: 2rem;
}
h2 {
margin-top: 1rem;
font-size: 1.5rem;
}
h3 {
margin-top: 1.5rem;
font-size: 1.25rem;
}
h4, h5, h6 {
margin-top: 1rem;
font-size: 1rem;
}
p {
margin: 0 0 1rem;
}
strong {
color: var(--base07);
}
ul, ol, dl {
margin-top: 0;
margin-bottom: 1rem;
}
dt {
font-weight: bold;
}
dd {
margin-bottom: .5rem;
}
code,
pre {
font-family: var(--code-font-family);
}
code {
padding: .25em .5em;
font-size: 85%;
color: var(--code-color);
background-color: var(--code-background-color);
border-radius: 3px;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
}
pre code {
padding: 0;
font-size: 100%;
color: inherit;
background-color: transparent;
}
/* Misc
========================================================================== */
/* React root entry point. */
#root {
height: 100%;
}

3
src/utils/getBaseUrl.js Normal file
View File

@ -0,0 +1,3 @@
const getBaseUrl = () => process.env.PUBLIC_URL || undefined;
export default getBaseUrl;

7115
yarn.lock Normal file

File diff suppressed because it is too large Load Diff