mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-04 09:15:58 +02:00
@@ -1,12 +1,9 @@
|
||||
import React from "react"
|
||||
import React, { PropsWithChildren } from "react"
|
||||
import * as SC from "./styles"
|
||||
|
||||
interface ContainerProps {
|
||||
children: React.ReactNode
|
||||
export function Container({
|
||||
children,
|
||||
...restProps
|
||||
}: PropsWithChildren<{}>): JSX.Element {
|
||||
return <SC.ContainerWrapper {...restProps}>{children}</SC.ContainerWrapper>
|
||||
}
|
||||
|
||||
const Container = ({ children, ...restProps }: ContainerProps): JSX.Element => (
|
||||
<SC.ContainerWrapper {...restProps}>{children}</SC.ContainerWrapper>
|
||||
)
|
||||
|
||||
export default Container
|
||||
|
||||
@@ -8,13 +8,11 @@
|
||||
import React, { PropsWithChildren } from "react"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
import Container from "../Container"
|
||||
import DocsSidebar from "../DocsSidebar"
|
||||
import { Main, MainContent } from "./styles"
|
||||
import Scrollbar from "react-perfect-scrollbar"
|
||||
import "react-perfect-scrollbar/dist/css/styles.css"
|
||||
import { DocsSidebar } from "../DocsSidebar"
|
||||
import { Footer } from "../Footer"
|
||||
import * as SC from "./styles"
|
||||
|
||||
const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
|
||||
export function DocsLayout({ children }: PropsWithChildren<{}>) {
|
||||
const data = useStaticQuery(graphql`
|
||||
query {
|
||||
site {
|
||||
@@ -27,20 +25,14 @@ const DocsLayout = ({ children }: PropsWithChildren<{}>) => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Main>
|
||||
<SC.Main>
|
||||
<DocsSidebar />
|
||||
<MainContent>
|
||||
<SC.MainContent>
|
||||
<h1>{data.site.siteMetadata.title}</h1>
|
||||
{children}
|
||||
</MainContent>
|
||||
</Main>
|
||||
<footer>
|
||||
© {new Date().getFullYear()}, Built with
|
||||
{` `}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a>
|
||||
</footer>
|
||||
</SC.MainContent>
|
||||
</SC.Main>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocsLayout
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// TODO: refactor this into styled components
|
||||
|
||||
html {
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,
|
||||
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you already use line highlighting
|
||||
*/
|
||||
|
||||
/* Adjust the position of the line numbers */
|
||||
.gatsby-highlight pre[class*="language-"].line-numbers {
|
||||
padding-left: 2.8em;
|
||||
}
|
||||
|
||||
/**
|
||||
* If you only want to use line numbering
|
||||
*/
|
||||
|
||||
.gatsby-highlight {
|
||||
background-color: #fdf6e3;
|
||||
border-radius: 0.3em;
|
||||
margin: 0.5em 0;
|
||||
padding: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.gatsby-highlight pre[class*="language-"].line-numbers {
|
||||
padding: 0;
|
||||
padding-left: 2.8em;
|
||||
overflow: initial;
|
||||
}
|
||||
@@ -1,99 +1,25 @@
|
||||
import * as R from "ramda"
|
||||
import React, { useState } from "react"
|
||||
import Tree from "react-treeview"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
import useBuildTree from "./useBuildTree"
|
||||
import * as SC from "./styles"
|
||||
|
||||
interface IFile {
|
||||
export interface IFile {
|
||||
title: string
|
||||
type: "file"
|
||||
path: string
|
||||
}
|
||||
|
||||
interface IFolder {
|
||||
export interface IFolder {
|
||||
title: string
|
||||
type: "folder"
|
||||
path: string
|
||||
children: IFileOrFolder[]
|
||||
}
|
||||
|
||||
type IFileOrFolder = IFile | IFolder
|
||||
export type IFileOrFolder = IFile | IFolder
|
||||
|
||||
const traverse = (
|
||||
[head, ...tail]: string[],
|
||||
basePath = "/docs"
|
||||
): IFileOrFolder => {
|
||||
const path = basePath + "/" + head
|
||||
const isFile = !tail.length
|
||||
if (isFile) {
|
||||
// probably not more than one dot
|
||||
const [name] = head.split(".")
|
||||
return {
|
||||
title: name,
|
||||
type: "file",
|
||||
path,
|
||||
}
|
||||
}
|
||||
return {
|
||||
title: head,
|
||||
type: "folder",
|
||||
path,
|
||||
children: [traverse(tail, path)],
|
||||
}
|
||||
}
|
||||
|
||||
const generateFolder = ({
|
||||
title,
|
||||
path,
|
||||
targets,
|
||||
}: {
|
||||
title: IFolder["title"]
|
||||
path: IFile["path"]
|
||||
targets: IFolder[]
|
||||
}): IFolder => {
|
||||
const children = join(R.chain(target => target.children, targets))
|
||||
|
||||
return {
|
||||
title,
|
||||
type: "folder",
|
||||
path,
|
||||
children,
|
||||
}
|
||||
}
|
||||
|
||||
const generateFile = ({
|
||||
title,
|
||||
path,
|
||||
}: {
|
||||
title: IFile["title"]
|
||||
path: IFile["path"]
|
||||
}): IFile => {
|
||||
return {
|
||||
title,
|
||||
path,
|
||||
type: "file",
|
||||
}
|
||||
}
|
||||
|
||||
const join = ([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] => {
|
||||
if (!head) return []
|
||||
|
||||
const [similarFs, remaining] = R.partition(
|
||||
obj => obj.title === head.title && obj.type === head.type,
|
||||
tail
|
||||
)
|
||||
const targets = [head, ...similarFs]
|
||||
const { title, path } = head
|
||||
|
||||
const current =
|
||||
head.type === "folder"
|
||||
? generateFolder({ title, path, targets: targets as IFolder[] })
|
||||
: generateFile({ title, path })
|
||||
|
||||
return [current, ...join(remaining)]
|
||||
}
|
||||
|
||||
interface IFileQuery {
|
||||
export interface IFileQuery {
|
||||
node: {
|
||||
relativePath: string
|
||||
childMarkdownRemark: {
|
||||
@@ -105,7 +31,7 @@ interface IFileQuery {
|
||||
}
|
||||
}
|
||||
|
||||
interface IAllDocsQuery {
|
||||
export interface IAllDocsQuery {
|
||||
allFile: {
|
||||
edges: IFileQuery[]
|
||||
}
|
||||
@@ -129,7 +55,7 @@ const ALL_DOCS = graphql`
|
||||
}
|
||||
`
|
||||
|
||||
const plantTree = (item: IFileOrFolder) => {
|
||||
function plantTree(item: IFileOrFolder) {
|
||||
if (item.type === "file") {
|
||||
return (
|
||||
<SC.PageLink to={item.path} activeClassName="active">
|
||||
@@ -158,21 +84,13 @@ function Folder({ item }: { item: IFolder }) {
|
||||
)
|
||||
}
|
||||
|
||||
const DocsSidebar = () => {
|
||||
export function DocsSidebar() {
|
||||
const docs = useStaticQuery<IAllDocsQuery>(ALL_DOCS)
|
||||
|
||||
const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) =>
|
||||
traverse(file.relativePath.split("/"))
|
||||
)
|
||||
const results = join(objects)
|
||||
|
||||
console.log(results)
|
||||
const tree = useBuildTree(docs)
|
||||
|
||||
return (
|
||||
<SC.DocsSidebarWrapper>
|
||||
{results.map(node => plantTree(node))}
|
||||
{tree.map(node => plantTree(node))}
|
||||
</SC.DocsSidebarWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocsSidebar
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
import * as R from "ramda"
|
||||
import {
|
||||
IFileOrFolder,
|
||||
IFile,
|
||||
IFolder,
|
||||
IAllDocsQuery,
|
||||
IFileQuery,
|
||||
} from "./index"
|
||||
|
||||
function traverse(
|
||||
[head, ...tail]: string[],
|
||||
basePath = "/docs"
|
||||
): IFileOrFolder {
|
||||
const path = basePath + "/" + head
|
||||
const isFile = !tail.length
|
||||
if (isFile) {
|
||||
// probably not more than one dot
|
||||
const [name] = head.split(".")
|
||||
return {
|
||||
title: name,
|
||||
type: "file",
|
||||
path,
|
||||
}
|
||||
}
|
||||
return {
|
||||
title: head,
|
||||
type: "folder",
|
||||
path,
|
||||
children: [traverse(tail, path)],
|
||||
}
|
||||
}
|
||||
|
||||
function generateFolder({
|
||||
title,
|
||||
path,
|
||||
targets,
|
||||
}: {
|
||||
title: IFolder["title"]
|
||||
path: IFile["path"]
|
||||
targets: IFolder[]
|
||||
}): IFolder {
|
||||
const children = join(R.chain(target => target.children, targets))
|
||||
|
||||
return {
|
||||
title,
|
||||
type: "folder",
|
||||
path,
|
||||
children,
|
||||
}
|
||||
}
|
||||
|
||||
function generateFile({
|
||||
title,
|
||||
path,
|
||||
}: {
|
||||
title: IFile["title"]
|
||||
path: IFile["path"]
|
||||
}): IFile {
|
||||
return {
|
||||
title,
|
||||
type: "file",
|
||||
path,
|
||||
}
|
||||
}
|
||||
|
||||
function join([head, ...tail]: IFileOrFolder[]): IFileOrFolder[] {
|
||||
if (!head) return []
|
||||
|
||||
const [similarFs, remaining] = R.partition(
|
||||
obj => obj.title === head.title && obj.type === head.type,
|
||||
tail
|
||||
)
|
||||
const targets = [head, ...similarFs]
|
||||
const { title, path } = head
|
||||
|
||||
const current =
|
||||
head.type === "folder"
|
||||
? generateFolder({ title, path, targets: targets as IFolder[] })
|
||||
: generateFile({ title, path })
|
||||
|
||||
return [current, ...join(remaining)]
|
||||
}
|
||||
|
||||
export default function useBuildTree(docs: IAllDocsQuery) {
|
||||
const objects = docs.allFile.edges.map(({ node: file }: IFileQuery) =>
|
||||
traverse(file.relativePath.split("/"))
|
||||
)
|
||||
|
||||
return join(objects)
|
||||
}
|
||||
@@ -1,20 +1,18 @@
|
||||
import React from "react"
|
||||
import { SidebarTitle } from "./style"
|
||||
import React, { PropsWithChildren } from "react"
|
||||
import * as SC from "./styles"
|
||||
|
||||
export interface DocsSidebarSectionProps {
|
||||
readonly title: string
|
||||
}
|
||||
|
||||
const DocsSidebarSection = ({
|
||||
export function DocsSidebarSection({
|
||||
title,
|
||||
children,
|
||||
}: React.PropsWithChildren<DocsSidebarSectionProps>) => {
|
||||
}: PropsWithChildren<DocsSidebarSectionProps>) {
|
||||
return (
|
||||
<div>
|
||||
<SidebarTitle>{title}</SidebarTitle>
|
||||
<SC.SidebarTitle>{title}</SC.SidebarTitle>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocsSidebarSection
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
import styled from "styled-components";
|
||||
import styled from "styled-components"
|
||||
|
||||
export const SidebarTitle = styled.h3`
|
||||
text-transform: uppercase;
|
||||
`;
|
||||
`
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from "react"
|
||||
import * as SC from "./styles"
|
||||
import { Container } from "../Container"
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<SC.FooterWrapper>
|
||||
<Container>
|
||||
© {new Date().getFullYear()}, Built with
|
||||
{` `}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a>
|
||||
</Container>
|
||||
</SC.FooterWrapper>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import { Link } from "gatsby"
|
||||
import styled from "styled-components"
|
||||
|
||||
export const FooterWrapper = styled.footer``
|
||||
@@ -8,15 +8,15 @@
|
||||
import React, { PropsWithChildren } from "react"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
import Container from "../Container"
|
||||
import Navbar from "../Navbar"
|
||||
import Sidebar from "../Sidebar"
|
||||
import { Container } from "../Container"
|
||||
import { Footer } from "../Footer"
|
||||
import { Sidebar } from "../Sidebar"
|
||||
import "./layout.scss"
|
||||
import { Main, MainContent } from "./styles"
|
||||
import * as SC from "./styles"
|
||||
import Scrollbar from "react-perfect-scrollbar"
|
||||
import "react-perfect-scrollbar/dist/css/styles.css"
|
||||
|
||||
const Layout = ({ children }: PropsWithChildren<{}>) => {
|
||||
export function Layout({ children }: PropsWithChildren<{}>) {
|
||||
const data = useStaticQuery(graphql`
|
||||
query {
|
||||
site {
|
||||
@@ -30,23 +30,15 @@ const Layout = ({ children }: PropsWithChildren<{}>) => {
|
||||
return (
|
||||
<Scrollbar>
|
||||
<Container>
|
||||
<Main>
|
||||
<SC.Main>
|
||||
<Sidebar />
|
||||
<MainContent>
|
||||
<SC.MainContent>
|
||||
<h1>{data.site.siteMetadata.title}</h1>
|
||||
{children}
|
||||
</MainContent>
|
||||
</Main>
|
||||
</SC.MainContent>
|
||||
</SC.Main>
|
||||
</Container>
|
||||
<footer>
|
||||
<Container>
|
||||
© {new Date().getFullYear()}, Built with
|
||||
{` `}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a>
|
||||
</Container>
|
||||
</footer>
|
||||
<Footer />
|
||||
</Scrollbar>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
|
||||
@@ -6,6 +6,7 @@ html {
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import { Link } from "gatsby";
|
||||
import * as React from "react";
|
||||
import icon from "./icon.png";
|
||||
import { HeaderWrapper } from "./styles";
|
||||
|
||||
// @todo maybe find alternative type for data
|
||||
const Navbar = ({ siteTitle }: any) => (
|
||||
<HeaderWrapper>
|
||||
<div
|
||||
style={{
|
||||
margin: `0 auto`,
|
||||
maxWidth: 960,
|
||||
padding: `1.45rem 1.0875rem`,
|
||||
}}
|
||||
>
|
||||
<div style={{ display: "flex", flexDirection: "row", alignItems: "center" }}>
|
||||
{/* <img src={icon} style={{ width: "70px" }} /> */}
|
||||
<h1 style={{ margin: 0 }}>
|
||||
<Link
|
||||
to="/"
|
||||
style={{
|
||||
color: `white`,
|
||||
textDecoration: `none`,
|
||||
}}
|
||||
>
|
||||
{siteTitle}
|
||||
</Link>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</HeaderWrapper>
|
||||
)
|
||||
|
||||
Navbar.propTypes = {
|
||||
siteTitle: String
|
||||
}
|
||||
|
||||
Navbar.defaultProps = {
|
||||
siteTitle: ``,
|
||||
}
|
||||
|
||||
export default Navbar;
|
||||
@@ -1,6 +0,0 @@
|
||||
import styled from "styled-components";
|
||||
|
||||
export const HeaderWrapper = styled.header`
|
||||
background: #ba1a2e;
|
||||
marginBottom: 1.45rem;
|
||||
`;
|
||||
@@ -3,13 +3,20 @@ import Helmet from "react-helmet"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
interface SEOProps {
|
||||
readonly description: string;
|
||||
readonly lang: string;
|
||||
readonly meta: object[];
|
||||
readonly title: string;
|
||||
readonly description?: string
|
||||
readonly lang?: string
|
||||
readonly meta?: any[]
|
||||
readonly keywords?: string[]
|
||||
readonly title: string
|
||||
}
|
||||
|
||||
const SEO = ({ description = "", lang = "en", meta = [], title }: SEOProps) => {
|
||||
export function SEO({
|
||||
description,
|
||||
lang = "en",
|
||||
meta = [],
|
||||
keywords = [],
|
||||
title,
|
||||
}: SEOProps) {
|
||||
const { site } = useStaticQuery(
|
||||
graphql`
|
||||
query {
|
||||
@@ -66,9 +73,16 @@ const SEO = ({ description = "", lang = "en", meta = [], title }: SEOProps) => {
|
||||
name: `twitter:description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
]}
|
||||
]
|
||||
.concat(
|
||||
keywords.length > 0
|
||||
? {
|
||||
name: `keywords`,
|
||||
content: keywords.join(`, `),
|
||||
}
|
||||
: []
|
||||
)
|
||||
.concat(meta)}
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
export default SEO
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from "react"
|
||||
import React, { PropsWithChildren } from "react"
|
||||
import logo from "../../images/tph-logo.png"
|
||||
import * as SC from "./styles"
|
||||
import ArrowRight from "../../icons/arrow-right.svg"
|
||||
|
||||
function MenuItem({ children, to }: { children: React.ReactNode; to: string }) {
|
||||
function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) {
|
||||
return (
|
||||
<SC.MenuItem to={to}>
|
||||
{children} <ArrowRight />
|
||||
@@ -11,7 +11,7 @@ function MenuItem({ children, to }: { children: React.ReactNode; to: string }) {
|
||||
)
|
||||
}
|
||||
|
||||
const Sidebar = () => {
|
||||
export function Sidebar() {
|
||||
return (
|
||||
<SC.SidebarWrapper>
|
||||
<SC.Logo src={logo} />
|
||||
@@ -27,5 +27,3 @@ const Sidebar = () => {
|
||||
</SC.SidebarWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
export default Sidebar
|
||||
|
||||
@@ -31,8 +31,8 @@ called `getMembers` that retrieves all the members in a discord server. When we
|
||||
function we see the following result.
|
||||
|
||||
```js
|
||||
const members = getMembers("The Programmers Hangout");
|
||||
console.log(members); // Promise {<pending>}
|
||||
const members = getMembers("The Programmers Hangout")
|
||||
console.log(members) // Promise {<pending>}
|
||||
```
|
||||
|
||||
Normally, we would have expected to see an array of all the members but it takes time to
|
||||
@@ -44,8 +44,8 @@ to access the actual members like so.
|
||||
|
||||
```js
|
||||
getMembers("The Programmers Hangout").then(members => {
|
||||
console.log(members); // (32k) [{...}, {...}, {...}]
|
||||
});
|
||||
console.log(members) // (32k) [{...}, {...}, {...}]
|
||||
})
|
||||
```
|
||||
|
||||
This way we are able to make sure that we only try to `console.log` when the `getMembers` function has resolved and ready to be used.
|
||||
@@ -63,15 +63,15 @@ You may have tried doing something like this before.
|
||||
|
||||
```js
|
||||
// Incorrect code, don't copy!
|
||||
let results;
|
||||
let results
|
||||
getWeather("Los Angeles").then(weather => {
|
||||
results = weather;
|
||||
});
|
||||
results = weather
|
||||
})
|
||||
console.log(results) // undefined
|
||||
```
|
||||
|
||||
Why is `results` undefined? Because **Javascript doesn't wait**. Whenever a Promise is created,
|
||||
your code will continue to run until there's no more code left in the stack. Only then
|
||||
your code will continue to run until there's no more code left in the stack. Only then
|
||||
will javascript try to run the `.then` callback of a Promise. Even if your Promise resolves
|
||||
immediately you are going to have to wait until you've run all the code in the stack before
|
||||
your `.then` callback has a chance to start running. This is due to the way the event loop works,
|
||||
@@ -81,8 +81,8 @@ In order to fix this problem we need to move the `console.log` inside the `.then
|
||||
|
||||
```js
|
||||
getWeather("Los Angeles").then(weather => {
|
||||
console.log(weather); // Sunny, probably
|
||||
});
|
||||
console.log(weather) // Sunny, probably
|
||||
})
|
||||
```
|
||||
|
||||
## Real World Example
|
||||
@@ -94,14 +94,14 @@ You can try it in your browser if you want to test it out.
|
||||
function getCharacters() {
|
||||
return fetch(`https://rickandmortyapi.com/api/character`)
|
||||
.then(response => response.json())
|
||||
.then(response => response.results);
|
||||
.then(response => response.results)
|
||||
}
|
||||
|
||||
getCharacters().then(characters => {
|
||||
console.log(characters); // (20) [{...}, {...}, {...}]
|
||||
});
|
||||
console.log(characters) // (20) [{...}, {...}, {...}]
|
||||
})
|
||||
```
|
||||
|
||||
Let's break down what's happening in this function
|
||||
|
||||
// TODO: finish this
|
||||
// TODO: finish this
|
||||
|
||||
@@ -15,9 +15,9 @@ function doAsync(number) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
doDatabase().then(function(dbResult) {
|
||||
otherDbFunction(dbResult).then(function(secondResult) {
|
||||
resolve(secondResult + 10);
|
||||
resolve(secondResult + 10)
|
||||
})
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
```
|
||||
@@ -29,9 +29,9 @@ already returns a promise, you can just return the original thing.
|
||||
function doAsync(number) {
|
||||
return doDatabase().then(function(dbResult) {
|
||||
otherDbFunction(dbResult).then(function(secondResult) {
|
||||
return secondResult + 10;
|
||||
return secondResult + 10
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -40,11 +40,13 @@ is that they allow you do chain them sequentially.
|
||||
|
||||
```js
|
||||
function doAsync(number) {
|
||||
return doDatabase().then(function(dbResult) {
|
||||
return otherDbFunction(dbResult)
|
||||
}).then(function(secondResult) {
|
||||
return secondResult + 10;
|
||||
});
|
||||
return doDatabase()
|
||||
.then(function(dbResult) {
|
||||
return otherDbFunction(dbResult)
|
||||
})
|
||||
.then(function(secondResult) {
|
||||
return secondResult + 10
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
@@ -56,17 +58,18 @@ function doAsync(number) {
|
||||
return doDatabase()
|
||||
.then(otherDbFunction)
|
||||
.then(function(secondResult) {
|
||||
return secondResult + 10;
|
||||
});
|
||||
return secondResult + 10
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
And you don't need those returns if you just have ES6 arrow functions
|
||||
|
||||
```js
|
||||
const doAsync = number => doDatabase()
|
||||
.then(otherDbFunction)
|
||||
.then(secondResult => secondResult + 10);
|
||||
const doAsync = number =>
|
||||
doDatabase()
|
||||
.then(otherDbFunction)
|
||||
.then(secondResult => secondResult + 10)
|
||||
```
|
||||
|
||||
Wow, that last one looks a lot cleaner to me than the first. Keeping that in mind, maybe we could be making some of our other functions cleaner as well
|
||||
|
||||
@@ -13,7 +13,6 @@ There are multiple benefits to using a singleton class
|
||||
- You're always going to pull the same instance of the class
|
||||
- It's only instantiated once
|
||||
- Use `$this` in a static-like context
|
||||
-
|
||||
|
||||
By using a singleton instead of a static class we expose a cleaner class to use and we can use regular instance properties instead of static properties.
|
||||
|
||||
@@ -28,13 +27,13 @@ namespace Example;
|
||||
|
||||
class Singleton
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* The singleton instance
|
||||
* @var Singleton
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
|
||||
/**
|
||||
* Get the instantiated singleton, or create it if it hasn't been instantiated yet.
|
||||
* @return Singleton
|
||||
@@ -44,7 +43,7 @@ class Singleton
|
||||
// static::$instance =?? new static();
|
||||
// The double ?'s is a null-coalesce operator. There's a link about it below.
|
||||
static::$instance = static::$instance ?? new static();
|
||||
|
||||
|
||||
return static::$instance;
|
||||
}
|
||||
|
||||
@@ -57,12 +56,12 @@ To give a little functionality to our freshly baked Singleton we add these three
|
||||
|
||||
```php
|
||||
private $word = "Pineapple";
|
||||
|
||||
|
||||
public function getWord(): string {
|
||||
// PHP_EOL is a constant for a new line (\r\n) or whichever your OS uses.
|
||||
return $this->word . PHP_EOL;
|
||||
}
|
||||
|
||||
|
||||
public function setWord(string $word): void {
|
||||
$this->word = $word;
|
||||
}
|
||||
|
||||
+11
-9
@@ -1,14 +1,16 @@
|
||||
import React from "react"
|
||||
|
||||
import Layout from "../components/Layout"
|
||||
import SEO from "../components/SEO"
|
||||
import { Layout } from "../components/Layout"
|
||||
import { SEO } from "../components/SEO"
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<Layout>
|
||||
<SEO title="404: Not found" />
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</Layout>
|
||||
)
|
||||
function NotFoundPage() {
|
||||
return (
|
||||
<Layout>
|
||||
<SEO title="404: Not found" />
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default NotFoundPage
|
||||
|
||||
+10
-8
@@ -1,13 +1,15 @@
|
||||
import React from "react"
|
||||
|
||||
import DocsLayout from "../components/DocsLayout"
|
||||
import SEO from "../components/SEO"
|
||||
import { DocsLayout } from "../components/DocsLayout"
|
||||
import { SEO } from "../components/SEO"
|
||||
|
||||
const DocsPage = () => (
|
||||
<DocsLayout>
|
||||
<SEO title="Docs" />
|
||||
the docs
|
||||
</DocsLayout>
|
||||
)
|
||||
function DocsPage() {
|
||||
return (
|
||||
<DocsLayout>
|
||||
<SEO title="Docs" />
|
||||
the docs
|
||||
</DocsLayout>
|
||||
)
|
||||
}
|
||||
|
||||
export default DocsPage
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Hello
|
||||
+14
-13
@@ -1,19 +1,20 @@
|
||||
import React from "react"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
import Layout from "../components/Layout"
|
||||
import SEO from "../components/SEO"
|
||||
import { Layout } from "../components/Layout"
|
||||
import { SEO } from "../components/SEO"
|
||||
|
||||
const IndexPage = () => (
|
||||
<Layout>
|
||||
<SEO title="Home" />
|
||||
<h1>Hi people</h1>
|
||||
<p>Welcome to your new Gatsby site.</p>
|
||||
<p>Now go build something great.</p>
|
||||
<div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
|
||||
</div>
|
||||
<Link to="/page-2/">Go to page 2</Link>
|
||||
</Layout>
|
||||
)
|
||||
function IndexPage() {
|
||||
return (
|
||||
<Layout>
|
||||
<SEO title="Home" />
|
||||
<h1>Hi people</h1>
|
||||
<p>Welcome to your new Gatsby site.</p>
|
||||
<p>Now go build something great.</p>
|
||||
<div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}></div>
|
||||
<Link to="/page-2/">Go to page 2</Link>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export default IndexPage
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from "react"
|
||||
import { graphql } from "gatsby"
|
||||
import SEO from "../components/SEO"
|
||||
import DocsLayout from "../components/DocsLayout"
|
||||
import { SEO } from "../components/SEO"
|
||||
import { DocsLayout } from "../components/DocsLayout"
|
||||
|
||||
// @todo maybe find alternative type for data
|
||||
const LanguagePost = ({ data }: any) => {
|
||||
function LanguagePost({ data }: any) {
|
||||
const { html, frontmatter } = data.file.post
|
||||
console.log(data)
|
||||
return (
|
||||
|
||||
Vendored
+1
@@ -1 +1,2 @@
|
||||
declare module "*.svg"
|
||||
declare module "*.png"
|
||||
|
||||
Reference in New Issue
Block a user