mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-07 23:43:57 +02:00
@@ -0,0 +1,35 @@
|
|||||||
|
import React, { useState } from "react"
|
||||||
|
|
||||||
|
interface SidebarProviderProps {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SidebarContextInterface {
|
||||||
|
current: number
|
||||||
|
setCurrent: (index: number) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SidebarContext = React.createContext<SidebarContextInterface | null>(
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
export function SidebarProvider({
|
||||||
|
children,
|
||||||
|
}: SidebarProviderProps): JSX.Element {
|
||||||
|
const [current, setCurrent] = useState(0)
|
||||||
|
|
||||||
|
function selectFirstLevel(index: number) {
|
||||||
|
setCurrent(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SidebarContext.Provider
|
||||||
|
value={{
|
||||||
|
current,
|
||||||
|
setCurrent: selectFirstLevel,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</SidebarContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,21 +2,12 @@ import styled, { css } from "styled-components"
|
|||||||
import {
|
import {
|
||||||
BASE_FONT_SIZE,
|
BASE_FONT_SIZE,
|
||||||
BASE_LINE_HEIGHT,
|
BASE_LINE_HEIGHT,
|
||||||
MODULAR_SCALE,
|
|
||||||
fontFamily,
|
fontFamily,
|
||||||
|
modularScale,
|
||||||
} from "../../design/typography"
|
} from "../../design/typography"
|
||||||
|
|
||||||
function modularFontSize(power: number) {
|
function modularScaleCSS(power: number) {
|
||||||
return BASE_FONT_SIZE * Math.pow(MODULAR_SCALE, power)
|
const { fontSize, lineHeight } = modularScale(power)
|
||||||
}
|
|
||||||
|
|
||||||
function modularScale(power: number) {
|
|
||||||
const fontSize = modularFontSize(power)
|
|
||||||
|
|
||||||
// attempt to fit line-height a little larger than font-size
|
|
||||||
const paddedLineHeight = fontSize * 1.1
|
|
||||||
const lineHeight =
|
|
||||||
paddedLineHeight - (paddedLineHeight % BASE_LINE_HEIGHT) + BASE_LINE_HEIGHT
|
|
||||||
|
|
||||||
return css`
|
return css`
|
||||||
font-size: ${fontSize}px;
|
font-size: ${fontSize}px;
|
||||||
@@ -28,6 +19,14 @@ export const MarkdownWrapper = styled.div`
|
|||||||
font-size: ${BASE_FONT_SIZE}px;
|
font-size: ${BASE_FONT_SIZE}px;
|
||||||
line-height: ${BASE_LINE_HEIGHT}px;
|
line-height: ${BASE_LINE_HEIGHT}px;
|
||||||
|
|
||||||
|
& > :first-child {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > :first-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: ${BASE_LINE_HEIGHT}px 0;
|
margin: ${BASE_LINE_HEIGHT}px 0;
|
||||||
}
|
}
|
||||||
@@ -45,26 +44,26 @@ export const MarkdownWrapper = styled.div`
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
${modularScale(6)};
|
${modularScaleCSS(6)};
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
${modularScale(5)};
|
${modularScaleCSS(5)};
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
${modularScale(4)};
|
${modularScaleCSS(4)};
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
${modularScale(3)};
|
${modularScaleCSS(3)};
|
||||||
}
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
${modularScale(2)};
|
${modularScaleCSS(2)};
|
||||||
}
|
}
|
||||||
|
|
||||||
h6 {
|
h6 {
|
||||||
${modularScale(1)};
|
${modularScaleCSS(1)};
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
import ChevronUp from "../../icons/chevron-up.svg"
|
||||||
|
import * as SC from "./styles"
|
||||||
|
|
||||||
|
interface ResourceHeaderProps {
|
||||||
|
title: any
|
||||||
|
authors: any
|
||||||
|
createdAt: any
|
||||||
|
timeToRead: any
|
||||||
|
recommendedReading: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ResourceHeader({
|
||||||
|
title,
|
||||||
|
authors,
|
||||||
|
createdAt,
|
||||||
|
timeToRead,
|
||||||
|
recommendedReading,
|
||||||
|
}: ResourceHeaderProps) {
|
||||||
|
const date = new Date(createdAt)
|
||||||
|
const month = date.toLocaleString("default", { month: "long" })
|
||||||
|
const day = date.getDate()
|
||||||
|
const year = date.getUTCFullYear()
|
||||||
|
const dateToHuman = `${month} ${day}, ${year}`
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SC.ResourceHeaderWrapper>
|
||||||
|
<SC.Title>{title}</SC.Title>
|
||||||
|
|
||||||
|
<SC.Top>
|
||||||
|
<SC.AuthorAvatars>
|
||||||
|
{authors.map(author => (
|
||||||
|
<SC.AuthorAvatar src={author.avatar} />
|
||||||
|
))}
|
||||||
|
</SC.AuthorAvatars>
|
||||||
|
<SC.Meta>
|
||||||
|
{authors.length} contributor{authors.lenght > 1 && "s"}
|
||||||
|
</SC.Meta>
|
||||||
|
<SC.Meta>{dateToHuman}</SC.Meta>
|
||||||
|
<SC.Meta>
|
||||||
|
{timeToRead} minute{timeToRead !== 1 && "s"} read time
|
||||||
|
</SC.Meta>
|
||||||
|
</SC.Top>
|
||||||
|
|
||||||
|
{recommendedReading && (
|
||||||
|
<SC.RecommendedReading>
|
||||||
|
Recommended reading
|
||||||
|
{recommendedReading.map(item => {
|
||||||
|
return (
|
||||||
|
<SC.ReadLink>
|
||||||
|
<ChevronUp /> <SC.ReadLinkText>{item}</SC.ReadLinkText>
|
||||||
|
</SC.ReadLink>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</SC.RecommendedReading>
|
||||||
|
)}
|
||||||
|
</SC.ResourceHeaderWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import styled from "styled-components"
|
||||||
|
import { fontFamily, modularScale } from "../../design/typography"
|
||||||
|
|
||||||
|
export const ResourceHeaderWrapper = styled.div`
|
||||||
|
border-bottom: 1px solid #dbdbdb;
|
||||||
|
padding-bottom: 32px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Top = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Title = styled.h1`
|
||||||
|
font-family: ${fontFamily.header};
|
||||||
|
font-size: ${modularScale(6).fontSize}px;
|
||||||
|
line-height: ${modularScale(6).lineHeight}px;
|
||||||
|
letter-spacing: -1.75px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const AuthorAvatars = styled.div`
|
||||||
|
margin-right: 16px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const AuthorAvatar = styled.img`
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border: 2px solid #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Meta = styled.div`
|
||||||
|
& + &::before {
|
||||||
|
content: "•";
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const RecommendedReading = styled.div`
|
||||||
|
margin-top: 16px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const ReadLink = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #04b0a6;
|
||||||
|
margin-top: 4px;
|
||||||
|
margin-left: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #045551;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
width: 14px;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg path {
|
||||||
|
fill: #04b0a6;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const ReadLinkText = styled.div`
|
||||||
|
text-decoration: underline;
|
||||||
|
`
|
||||||
@@ -6,35 +6,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { PropsWithChildren } from "react"
|
import React, { PropsWithChildren } from "react"
|
||||||
import { useStaticQuery, graphql } from "gatsby"
|
|
||||||
|
|
||||||
import { GlobalStyles } from "../../globalStyles"
|
import { GlobalStyles } from "../../globalStyles"
|
||||||
import { ResourcesSidebar } from "../ResourcesSidebar"
|
import { ResourcesSidebar } from "../ResourcesSidebar"
|
||||||
import { Footer } from "../Footer"
|
|
||||||
import * as SC from "./styles"
|
import * as SC from "./styles"
|
||||||
|
import { SidebarProvider } from "../../SidebarProvider"
|
||||||
|
|
||||||
export function ResourcesLayout({ children }: PropsWithChildren<{}>) {
|
export function ResourcesLayout({ children }: PropsWithChildren<{}>) {
|
||||||
const data = useStaticQuery(graphql`
|
|
||||||
query {
|
|
||||||
site {
|
|
||||||
siteMetadata {
|
|
||||||
title
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<SidebarProvider>
|
||||||
<GlobalStyles />
|
<GlobalStyles />
|
||||||
<SC.Main>
|
<SC.Main>
|
||||||
<ResourcesSidebar />
|
<ResourcesSidebar />
|
||||||
<SC.MainContent>
|
<SC.MainContent>
|
||||||
<h1>{data.site.siteMetadata.title}</h1>
|
<SC.Container>{children}</SC.Container>
|
||||||
{children}
|
|
||||||
</SC.MainContent>
|
</SC.MainContent>
|
||||||
</SC.Main>
|
</SC.Main>
|
||||||
<Footer />
|
</SidebarProvider>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,13 @@ import styled from "styled-components"
|
|||||||
|
|
||||||
export const Main = styled.div`
|
export const Main = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
margin: 128px auto 64px !important;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
`
|
`
|
||||||
|
|
||||||
export const MainContent = styled.main`
|
export const MainContent = styled.main`
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
|
margin-top: 128px;
|
||||||
|
|
||||||
& > :first-child {
|
& > :first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@@ -17,3 +18,8 @@ export const MainContent = styled.main`
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export const Container = styled.div`
|
||||||
|
width: 650px;
|
||||||
|
margin: 0 auto;
|
||||||
|
`
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import React, { useState } from "react"
|
|||||||
import Tree from "react-treeview"
|
import Tree from "react-treeview"
|
||||||
import { useStaticQuery, graphql } from "gatsby"
|
import { useStaticQuery, graphql } from "gatsby"
|
||||||
import useBuildTree from "./useBuildTree"
|
import useBuildTree from "./useBuildTree"
|
||||||
|
import useSidebar from "./../../hooks/useSidebar"
|
||||||
|
import banner from "../../images/tph-banner.png"
|
||||||
import * as SC from "./styles"
|
import * as SC from "./styles"
|
||||||
|
|
||||||
export interface IFile {
|
export interface IFile {
|
||||||
@@ -56,32 +58,63 @@ const ALL_RESOURCES = graphql`
|
|||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
function plantTree(item: IFileOrFolder) {
|
function plantTree(item: IFileOrFolder, index?: number, firstLevel?: boolean) {
|
||||||
if (item.type === "file") {
|
if (item.type === "file") {
|
||||||
return (
|
return (
|
||||||
<SC.PageLink to={item.path} activeClassName="active">
|
<SC.PageLink key={item.title} to={item.path} activeClassName="active">
|
||||||
{item.title}
|
{item.title}
|
||||||
</SC.PageLink>
|
</SC.PageLink>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Folder item={item} />
|
if (firstLevel && index !== undefined) {
|
||||||
|
return <FirstLevelFolder key={item.title} item={item} index={index} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Folder key={item.title} item={item} />
|
||||||
}
|
}
|
||||||
|
|
||||||
function Folder({ item }: { item: IFolder }) {
|
function Folder({ item }: { item: IFolder }) {
|
||||||
const [collapsed, setCollapse] = useState(false)
|
const [collapsed, setCollapse] = useState(true)
|
||||||
|
|
||||||
function toggleCollapse() {
|
function toggleCollapse() {
|
||||||
setCollapse(prevState => !prevState)
|
setCollapse(prevState => !prevState)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tree
|
<SC.TreeWrapper>
|
||||||
collapsed={collapsed}
|
<Tree
|
||||||
nodeLabel={<div onClick={toggleCollapse}>{item.title}</div>}
|
collapsed={collapsed}
|
||||||
>
|
nodeLabel={<SC.Label onClick={toggleCollapse}>{item.title}</SC.Label>}
|
||||||
{item.children.map(plantTree)}
|
>
|
||||||
</Tree>
|
{item.children.map(node => plantTree(node))}
|
||||||
|
</Tree>
|
||||||
|
</SC.TreeWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function FirstLevelFolder({ item, index }: { item: IFolder; index: number }) {
|
||||||
|
const { current, setCurrent } = useSidebar()
|
||||||
|
const collapsed = current !== index
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SC.TreeWrapper>
|
||||||
|
<Tree
|
||||||
|
className="firstLevel"
|
||||||
|
collapsed={collapsed}
|
||||||
|
nodeLabel={
|
||||||
|
<SC.FirstLabel
|
||||||
|
className={!collapsed ? "active" : undefined}
|
||||||
|
onClick={() => setCurrent(index)}
|
||||||
|
>
|
||||||
|
{item.title}
|
||||||
|
<SC.CollapseToggler />
|
||||||
|
</SC.FirstLabel>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{item.children.map(node => plantTree(node))}
|
||||||
|
</Tree>
|
||||||
|
</SC.TreeWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +124,10 @@ export function ResourcesSidebar() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SC.ResourcesSidebarWrapper>
|
<SC.ResourcesSidebarWrapper>
|
||||||
{tree.map(node => plantTree(node))}
|
<SC.Banner src={banner} />
|
||||||
|
<SC.Inner>
|
||||||
|
{tree.map((node, index) => plantTree(node, index, true))}
|
||||||
|
</SC.Inner>
|
||||||
</SC.ResourcesSidebarWrapper>
|
</SC.ResourcesSidebarWrapper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,111 @@
|
|||||||
import styled from "styled-components"
|
import styled from "styled-components"
|
||||||
import { Link } from "gatsby"
|
import { Link } from "gatsby"
|
||||||
|
import ChevronUp from "../../icons/chevron-up.svg"
|
||||||
|
|
||||||
export const ResourcesSidebarWrapper = styled.div`
|
export const ResourcesSidebarWrapper = styled.div`
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 16px;
|
|
||||||
flex: 0 0 300px;
|
flex: 0 0 300px;
|
||||||
|
background: #f9f9f9;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Banner = styled.img`
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const TreeWrapper = styled.div`
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& + & {
|
||||||
|
border-top: 1px solid #dbdbdb;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Label = styled.div`
|
||||||
|
padding: 4px 0;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const FirstLabel = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px 12px 0;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #a9a9a9;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
margin-left: auto;
|
||||||
|
transform: rotate(90deg);
|
||||||
|
transition: transform 0.3s;
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: #a9a9a9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active svg {
|
||||||
|
transform: rotate(0);
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const CollapseToggler = styled(ChevronUp)``
|
||||||
|
|
||||||
|
export const Inner = styled.div`
|
||||||
|
padding-top: 30px;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
.tree-view {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_item {
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_children {
|
||||||
|
margin-left: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_children-collapsed {
|
||||||
|
height: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_arrow {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 6px;
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_arrow:after {
|
||||||
|
content: "▾";
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_arrow.firstLevel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-view_arrow-collapsed {
|
||||||
|
-webkit-transform: rotate(-90deg);
|
||||||
|
-moz-transform: rotate(-90deg);
|
||||||
|
-ms-transform: rotate(-90deg);
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const PageLink = styled(Link)`
|
export const PageLink = styled(Link)`
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ created_at: 2019/07/27
|
|||||||
title: Callbacks
|
title: Callbacks
|
||||||
---
|
---
|
||||||
|
|
||||||
# Callbacks are everywhere
|
## Callbacks are everywhere
|
||||||
|
|
||||||
If you've been doing javascript for any amount of time you'll have noticed that callbacks appear in just about every single piece of code.
|
If you've been doing javascript for any amount of time you'll have noticed that callbacks appear in just about every single piece of code.
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
authors:
|
authors:
|
||||||
- "veksen#1060"
|
- "veksen#1060"
|
||||||
created_at: "2019/07/27"
|
created_at: "2019/07/27"
|
||||||
|
title: Iterative vs Functional array helpers
|
||||||
---
|
---
|
||||||
|
|
||||||
# Iterative vs Functional array helpers
|
|
||||||
|
|
||||||
-- placeholder --
|
-- placeholder --
|
||||||
|
|
||||||
## find
|
## find
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ recommended_reading:
|
|||||||
- javascript/es6/arrow-functions
|
- javascript/es6/arrow-functions
|
||||||
---
|
---
|
||||||
|
|
||||||
# A Promise to Keep
|
## A Promise to Keep
|
||||||
|
|
||||||
A `Promise` in Javascript represents an action that has already started, but one that will be
|
A `Promise` in Javascript represents an action that has already started, but one that will be
|
||||||
completed at a later time. Much like in real life, when you create a promise, you are expected
|
completed at a later time. Much like in real life, when you create a promise, you are expected
|
||||||
to fulfill that promise. However, sometimes things go wrong where you can no longer fulfill
|
to fulfill that promise. However, sometimes things go wrong where you can no longer fulfill
|
||||||
a promise you made. This is essentially the main idea behind how promises work in javascript.
|
a promise you made. This is essentially the main idea behind how promises work in javascript.
|
||||||
|
|
||||||
## Basics
|
### Basics
|
||||||
|
|
||||||
When you create a Promise or call a function that returns a Promise in Javascript, you're left
|
When you create a Promise or call a function that returns a Promise in Javascript, you're left
|
||||||
with an object that can either resolve into the actual value that you were promised, or it
|
with an object that can either resolve into the actual value that you were promised, or it
|
||||||
@@ -24,7 +24,7 @@ can reject and leave you with an error for why that promise failed.
|
|||||||
|
|
||||||
We can access these values using the `.then` and `.catch` methods on the `Promise` object respectively.
|
We can access these values using the `.then` and `.catch` methods on the `Promise` object respectively.
|
||||||
|
|
||||||
## A Simple Example
|
### A Simple Example
|
||||||
|
|
||||||
First, let's explore a bit of a made-up example. Imagine we have a promise-returning function
|
First, let's explore a bit of a made-up example. Imagine we have a promise-returning function
|
||||||
called `getMembers` that retrieves all the members in a discord server. When we execute this
|
called `getMembers` that retrieves all the members in a discord server. When we execute this
|
||||||
@@ -50,7 +50,7 @@ getMembers("The Programmers Hangout").then(members => {
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Beginner Mistakes
|
### Beginner Mistakes
|
||||||
|
|
||||||
Promises are possibly the #1 most common source of confusion for beginners. In order
|
Promises are possibly the #1 most common source of confusion for beginners. In order
|
||||||
to avoid falling in pitfalls yourself, you have to remember 2 things about Javascript when
|
to avoid falling in pitfalls yourself, you have to remember 2 things about Javascript when
|
||||||
@@ -85,7 +85,7 @@ getWeather("Los Angeles").then(weather => {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Real World Example
|
### Real World Example
|
||||||
|
|
||||||
Here is a real function that gets character information from the Rick and Morty API.
|
Here is a real function that gets character information from the Rick and Morty API.
|
||||||
You can try it in your browser if you want to test it out.
|
You can try it in your browser if you want to test it out.
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
authors:
|
authors:
|
||||||
- "Xetera#0001"
|
- "Xetera#0001"
|
||||||
created_at: "2019/07/26"
|
created_at: "2019/07/26"
|
||||||
|
title: Simplifying Promises
|
||||||
---
|
---
|
||||||
|
|
||||||
# Simplifying Promises
|
|
||||||
|
|
||||||
-- placeholder --
|
-- placeholder --
|
||||||
|
|
||||||
The first naive attempt, using new Promise for something that already returns a promise.
|
The first naive attempt, using new Promise for something that already returns a promise.
|
||||||
|
|||||||
@@ -2,10 +2,9 @@
|
|||||||
authors:
|
authors:
|
||||||
- "supergrecko#3434"
|
- "supergrecko#3434"
|
||||||
created_at: "2019/07/27"
|
created_at: "2019/07/27"
|
||||||
|
title: Singletons
|
||||||
---
|
---
|
||||||
|
|
||||||
# Singletons
|
|
||||||
|
|
||||||
A singleton is a class which is only instantiated once during runtime. This is done by keeping a static property containing its instance on the singleton class.
|
A singleton is a class which is only instantiated once during runtime. This is done by keeping a static property containing its instance on the singleton class.
|
||||||
|
|
||||||
There are multiple benefits to using a singleton class
|
There are multiple benefits to using a singleton class
|
||||||
@@ -16,7 +15,7 @@ There are multiple benefits to using a singleton class
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
# Creating a Singleton in PHP
|
## Creating a Singleton in PHP
|
||||||
|
|
||||||
Creating a class which can be used as a singleton is very simple.
|
Creating a class which can be used as a singleton is very simple.
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ class Singleton
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Testing our Singleton
|
## Testing our Singleton
|
||||||
|
|
||||||
To give a little functionality to our freshly baked Singleton we add these three members to the class
|
To give a little functionality to our freshly baked Singleton we add these three members to the class
|
||||||
|
|
||||||
@@ -93,7 +92,7 @@ $first->setWord("Banana");
|
|||||||
var_dump($first->getWord() === $second->getWord()); // bool(true)
|
var_dump($first->getWord() === $second->getWord()); // bool(true)
|
||||||
```
|
```
|
||||||
|
|
||||||
# Further Research
|
## Further Research
|
||||||
|
|
||||||
Here's a couple links which will help you understand Singletons better.
|
Here's a couple links which will help you understand Singletons better.
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
authors:
|
authors:
|
||||||
- "Xetera#0001"
|
- "Xetera#0001"
|
||||||
date: 2019/06/26
|
date: 2019/06/26
|
||||||
|
title: Some Python Article
|
||||||
---
|
---
|
||||||
|
|
||||||
# Python
|
## Python
|
||||||
|
|
||||||
This is a placeholder post
|
This is a placeholder post
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,24 @@ export const BASE_FONT_SIZE = 18
|
|||||||
export const BASE_LINE_HEIGHT = 25
|
export const BASE_LINE_HEIGHT = 25
|
||||||
export const MODULAR_SCALE = 1.1487
|
export const MODULAR_SCALE = 1.1487
|
||||||
|
|
||||||
|
function modularFontSize(power: number) {
|
||||||
|
return BASE_FONT_SIZE * Math.pow(MODULAR_SCALE, power)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function modularScale(power: number) {
|
||||||
|
const fontSize = modularFontSize(power)
|
||||||
|
|
||||||
|
// attempt to fit line-height a little larger than font-size
|
||||||
|
const paddedLineHeight = fontSize * 1.1
|
||||||
|
const lineHeight =
|
||||||
|
paddedLineHeight - (paddedLineHeight % BASE_LINE_HEIGHT) + BASE_LINE_HEIGHT
|
||||||
|
|
||||||
|
return {
|
||||||
|
fontSize,
|
||||||
|
lineHeight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const fontFamily = {
|
export const fontFamily = {
|
||||||
header: FONT_MONTSERRAT,
|
header: FONT_MONTSERRAT,
|
||||||
body: FONT_OXYGEN,
|
body: FONT_OXYGEN,
|
||||||
|
|||||||
+1
-47
@@ -11,6 +11,7 @@ export const GlobalStyles = createGlobalStyle`
|
|||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
|
margin: 0;
|
||||||
font-size: ${BASE_FONT_SIZE}px;
|
font-size: ${BASE_FONT_SIZE}px;
|
||||||
line-height: ${BASE_LINE_HEIGHT}px;
|
line-height: ${BASE_LINE_HEIGHT}px;
|
||||||
}
|
}
|
||||||
@@ -33,51 +34,4 @@ export const GlobalStyles = createGlobalStyle`
|
|||||||
padding-left: 2.8em;
|
padding-left: 2.8em;
|
||||||
overflow: initial;
|
overflow: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: probably extract this */
|
|
||||||
.tree-view {
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_item {
|
|
||||||
display: flex;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_item,
|
|
||||||
.tree-view_children > div {
|
|
||||||
padding: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_children {
|
|
||||||
margin-left: 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_children-collapsed {
|
|
||||||
height: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_arrow {
|
|
||||||
cursor: pointer;
|
|
||||||
margin-right: 6px;
|
|
||||||
display: inline-block;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_arrow:after {
|
|
||||||
content: "▾";
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-view_arrow-collapsed {
|
|
||||||
-webkit-transform: rotate(-90deg);
|
|
||||||
-moz-transform: rotate(-90deg);
|
|
||||||
-ms-transform: rotate(-90deg);
|
|
||||||
transform: rotate(-90deg);
|
|
||||||
}
|
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { useContext } from "react"
|
||||||
|
import { SidebarContext, SidebarContextInterface } from "../SidebarProvider"
|
||||||
|
|
||||||
|
export default function useSidebar(): SidebarContextInterface {
|
||||||
|
const sidebarContext = useContext(SidebarContext)
|
||||||
|
|
||||||
|
if (!sidebarContext) {
|
||||||
|
throw Error("Need context")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sidebarContext
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="15" height="8" viewBox="0 0 15 8" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.72578 0.21176L0.213835 6.72587C-0.0712782 7.01171 -0.0712782 7.47481 0.213835 7.76136C0.498947 8.0472 0.962045 8.0472 1.24716 7.76136L7.24241 1.76394L13.2377 7.76064C13.5228 8.04648 13.9859 8.04648 14.2717 7.76064C14.5568 7.47481 14.5568 7.01099 14.2717 6.72515L7.75976 0.211038C7.47759 -0.0704669 7.00722 -0.070466 6.72578 0.21176Z" fill="black"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 462 B |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -3,14 +3,22 @@ import { graphql } from "gatsby"
|
|||||||
import { Markdown } from "../components/Markdown"
|
import { Markdown } from "../components/Markdown"
|
||||||
import { SEO } from "../components/SEO"
|
import { SEO } from "../components/SEO"
|
||||||
import { ResourcesLayout } from "../components/ResourcesLayout"
|
import { ResourcesLayout } from "../components/ResourcesLayout"
|
||||||
|
import { ResourceHeader } from "../components/ResourceHeader"
|
||||||
|
|
||||||
// @todo maybe find alternative type for data
|
// @todo maybe find alternative type for data
|
||||||
function LanguagePost({ data }: any) {
|
function LanguagePost({ data }: any) {
|
||||||
const { html, frontmatter } = data.file.post
|
const { html, fields, frontmatter, timeToRead } = data.file.post
|
||||||
console.log(data)
|
console.log(data)
|
||||||
return (
|
return (
|
||||||
<ResourcesLayout>
|
<ResourcesLayout>
|
||||||
<SEO title={frontmatter.title} />
|
<SEO title={frontmatter.title} />
|
||||||
|
<ResourceHeader
|
||||||
|
title={frontmatter.title}
|
||||||
|
authors={fields.authors}
|
||||||
|
createdAt={frontmatter.created_at}
|
||||||
|
timeToRead={timeToRead}
|
||||||
|
recommendedReading={frontmatter.recommended_reading}
|
||||||
|
/>
|
||||||
<Markdown content={html} />
|
<Markdown content={html} />
|
||||||
</ResourcesLayout>
|
</ResourcesLayout>
|
||||||
)
|
)
|
||||||
@@ -31,9 +39,11 @@ export const query = graphql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
frontmatter {
|
frontmatter {
|
||||||
date
|
created_at
|
||||||
title
|
title
|
||||||
|
recommended_reading
|
||||||
}
|
}
|
||||||
|
timeToRead
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user