Signed-off-by: Avior <florian.bouillon@delta-wings.net>
This commit is contained in:
Florian Bouillon 2020-02-06 00:39:09 +01:00
parent 32e09522bc
commit a5db5b9dbe
No known key found for this signature in database
GPG Key ID: B143FF27EF555D16
24 changed files with 1476 additions and 953 deletions

View File

@ -1,6 +1,7 @@
import Link from 'next/link' import Link from 'next/link'
import React from 'react' import React from 'react'
import { ChevronRight } from 'react-feather' import { ChevronRight } from 'react-feather'
import Picture from './Picture'
interface Props { interface Props {
title: string title: string
@ -37,11 +38,7 @@ export default class Element extends React.Component<Props, {}> {
<div> <div>
<Link href="/[category]/[slug]" as={this.props.link}> <Link href="/[category]/[slug]" as={this.props.link}>
{this.props.image ? ( {this.props.image ? (
<a><picture> <a aria-label={this.props.title}><Picture src={this.props.image} alt={this.props.alt} style={{height: 250, borderRadius: 10}} /></a> //<img src={require(`../images${this.props.image}`/*this.props.image*/)} alt={this.props.alt}/>
<source srcSet={require(`../images${this.props.image}?webp`)} type="image/webp" />
<source srcSet={require(`../images${this.props.image}`)} type="image/png" />
<img src={require(`../images${this.props.image}`)} />
</picture></a> //<img src={require(`../images${this.props.image}`/*this.props.image*/)} alt={this.props.alt}/>
) : ( ) : (
<div></div> <div></div>
)} )}
@ -53,7 +50,7 @@ export default class Element extends React.Component<Props, {}> {
<a>{this.props.title}</a> <a>{this.props.title}</a>
</Link> </Link>
<Link href="/[category]/[slug]" as={this.props.link}> <Link href="/[category]/[slug]" as={this.props.link}>
<a><ChevronRight size={48}/></a> <a aria-label={this.props.title}><ChevronRight size={48}/></a>
</Link> </Link>
</span> </span>
<style jsx>{` <style jsx>{`
@ -67,12 +64,7 @@ export default class Element extends React.Component<Props, {}> {
min-width: 400px; min-width: 400px;
} }
} }
img {
width: 100%;
border-radius: 10px;
height: 250px;
object-fit: cover;
}
span { span {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;

View File

@ -23,9 +23,9 @@ export default class Filters extends React.Component<Props, States> {
public render() { public render() {
return ( return (
<aside> <aside>
<div>Trier</div> <label htmlFor="sidebar-sort">Trier</label>
<div className="input icon-right"> <div className="input icon-right">
<select onChangeCapture={this.onChange}> <select onChangeCapture={this.onChange} id="sidebar-sort">
<option value="true">plus récent au moins récent</option> <option value="true">plus récent au moins récent</option>
<option value="false">moins récent au plus récent</option> <option value="false">moins récent au plus récent</option>
</select> </select>
@ -33,9 +33,9 @@ export default class Filters extends React.Component<Props, States> {
<ChevronDown /> <ChevronDown />
</i> </i>
</div> </div>
<div>Filtrer</div> <label htmlFor="sidebar-filter">Filtrer</label>
<div className="input icon-right inline"> <div className="input icon-right inline">
<input placeholder="ex: dzeio.com" type="text" ref={this.setInput} onKeyDownCapture={this.onKeyDown} /> <input id="sidebar-filter" placeholder="ex: dzeio.com" type="text" ref={this.setInput} onKeyDownCapture={this.onKeyDown} />
<i> <i>
<ChevronRight onClick={this.onClick} /> <ChevronRight onClick={this.onClick} />
</i> </i>
@ -72,7 +72,7 @@ export default class Filters extends React.Component<Props, States> {
flex-grow: 1; flex-grow: 1;
} }
div:not(.input) { div:not(.input), label {
display: block; display: block;
padding: 20px; padding: 20px;
margin: 10px 0; margin: 10px 0;

View File

@ -10,19 +10,19 @@ export default class Footer extends React.Component<{}, {}> {
<div className="pre"></div> <div className="pre"></div>
<div className="footer"> <div className="footer">
<span> <span>
<a href="mailto:contact@avior.me" target="_blank"> <a aria-label="Email Address" href="mailto:contact@avior.me" target="_blank">
<Mail color={config.colors[500]} /> <Mail color={config.colors[500]} />
</a> </a>
<a href="tel:+33672292683" target="_blank"> <a aria-label="Phone Number" href="tel:+33672292683" target="_blank">
<PhoneCall color={config.colors[500]} /> <PhoneCall color={config.colors[500]} />
</a> </a>
<a href="https://git.delta-wings.net" target="_blank"> <a aria-label="Git" rel="noopener noreferrer" href="https://git.delta-wings.net" target="_blank">
<GitHub color={config.colors[500]} /> <GitHub color={config.colors[500]} />
</a> </a>
<a href="https://twitter.com/aviortheking" target="_blank"> <a aria-label="Twitter" rel="nofollow noopener noreferrer" href="https://twitter.com/aviortheking" target="_blank">
<Twitter color={config.colors[500]} /> <Twitter color={config.colors[500]} />
</a> </a>
<a href="https://www.linkedin.com/in/florian-bouillon/" target="_blank"> <a aria-label="linkdedin" rel="nofollow noopener noreferrer" href="https://www.linkedin.com/in/florian-bouillon/" target="_blank">
<Linkedin color={config.colors[500]} /> <Linkedin color={config.colors[500]} />
</a> </a>
</span> </span>
@ -64,3 +64,9 @@ export default class Footer extends React.Component<{}, {}> {
) )
} }
} }
/*
rel="nofollow noopener noreferrer"
nofollow links not endorsed by the website
noopener target can't use `window.opener` but still send the HTTP Header Referer
noreferrer dont send the HTTP Header Referer
*/

View File

@ -58,7 +58,7 @@ export default class Navbar extends React.Component<Props, States> {
<hr /> <hr />
<div className="head"> <div className="head">
<Link href="/"> <Link href="/">
<a><img src="/logo.svg" alt=""/></a> <a><img src="/logo.svg" alt="logo"/></a>
</Link> </Link>
<span onClick={this.onClick} data-menu={this.refs.menu}> <span onClick={this.onClick} data-menu={this.refs.menu}>
<Menu size={30} /> <Menu size={30} />

20
components/Picture.tsx Normal file
View File

@ -0,0 +1,20 @@
import { Component, CSSProperties } from "react"
interface props {
src: string,
alt?: string,
style?: CSSProperties
parentStyle?: CSSProperties
}
export default class Picture extends Component<props, {}> {
public render() {
const sets = require(`../images${this.props.src}?resize&sizes[]=300&sizes[]=600&sizes[]=1000`)
return (
<picture style={this.props.parentStyle}>
<source srcSet={require(`../images${this.props.src}?webp`).default} type="image/webp" />
<img srcSet={sets.srcSet} src={sets.src} alt={this.props.alt} style={Object.assign({width: "100%", objectFit: "cover"}, this.props.style)} />
</picture>
)
}
}

View File

@ -25,11 +25,12 @@
"jimp": "^0.9.3", "jimp": "^0.9.3",
"lqip-loader": "^2.2.0", "lqip-loader": "^2.2.0",
"next": "^9.1.7", "next": "^9.1.7",
"next-offline": "^4.0.6", "next-offline": "^5.0.0",
"next-optimized-images": "^2.5.4", "next-optimized-images": "^2.5.4",
"node-emoji": "^1.10.0", "node-emoji": "^1.10.0",
"raw-loader": "^4.0.0", "raw-loader": "^4.0.0",
"react": "^16.12.0", "react": "^16.12.0",
"react-amphtml": "^4.0.2",
"react-dom": "^16.12.0", "react-dom": "^16.12.0",
"react-feather": "^2.0.3", "react-feather": "^2.0.3",
"react-markdown": "^4.3.0", "react-markdown": "^4.3.0",
@ -38,6 +39,7 @@
"serve": "^11.3.0", "serve": "^11.3.0",
"stylus": "^0.54.7", "stylus": "^0.54.7",
"svg-sprite-loader": "^4.1.6", "svg-sprite-loader": "^4.1.6",
"ts-node": "^8.6.2",
"typescript": "^3.7.4", "typescript": "^3.7.4",
"webp-loader": "^0.6.0", "webp-loader": "^0.6.0",
"webpack": "^4.41.5", "webpack": "^4.41.5",

View File

@ -6,6 +6,7 @@ import { Component } from 'react'
import ReactMarkdown from 'react-markdown/with-html' import ReactMarkdown from 'react-markdown/with-html'
import Post from '../../components/Post' import Post from '../../components/Post'
import Picture from '../../components/Picture'
import config from '../../config' import config from '../../config'
import Error from '../_error' import Error from '../_error'
@ -57,11 +58,12 @@ export default class PostPage extends Component<Props, States> {
<Error statusCode={404} /> <Error statusCode={404} />
) : ( ) : (
<div> <div>
<picture> <Picture src={this.props.post.header.image} alt={this.props.post.header.imageAlt} parentStyle={{zIndex: 999}} style={{
<source srcSet={require(`../../images${this.props.post.header.image}?webp`)} type="image/webp" /> maxWidth: "100%",
<source srcSet={require(`../../images${this.props.post.header.image}`)} type="image/png" /> borderRadius: 10,
<img src={require(`../../images${this.props.post.header.image}`)} alt={this.props.post.header.imageAlt} /> maxHeight: 300,
</picture> boxShadow: "0px 0px 4px rgba(0, 0, 0, 0.4)"
}}/>
<ReactMarkdown escapeHtml={false} source={emoji.emojify(this.props.post.content, null, (code, name) => `<span class="emoji">${code}</span>`)}/> <ReactMarkdown escapeHtml={false} source={emoji.emojify(this.props.post.content, null, (code, name) => `<span class="emoji">${code}</span>`)}/>
<h2>Détails</h2> <h2>Détails</h2>
<p>Tags:</p> <p>Tags:</p>

View File

@ -7,16 +7,25 @@ import config from '../config'
import '../styl/styl.styl' import '../styl/styl.styl'
class MyApp extends App { class MyApp extends App {
public componentDidMount() {
if (window.location.origin !== config.domain && window.location.hostname !== "localhost") {
window.location.replace(`${config.domain}${window.location.pathname}`)
}
}
public render() { public render() {
const { Component, pageProps } = this.props const { Component, pageProps } = this.props
return( return(
<Layout> <Layout>
<Head> <Head>
{/* General */}
<title key="title">{config.og.title}</title>
<meta key="description" name="description" content={config.og.description}/> <meta key="description" name="description" content={config.og.description}/>
{/* Open Graph / Twitter */}
<meta key="og:url" property="og:url" content={config.domain + this.props.router.asPath} /> <meta key="og:url" property="og:url" content={config.domain + this.props.router.asPath} />
<title key="title">{config.og.title}</title>
<meta key="og:title" property="og:title" content={config.og.title}/> <meta key="og:title" property="og:title" content={config.og.title}/>
<meta key="og:description" property="og:description" content={config.og.description}/> <meta key="og:description" property="og:description" content={config.og.description}/>
<meta key="og:type" property="og:type" content="website" /> <meta key="og:type" property="og:type" content="website" />

View File

@ -15,14 +15,29 @@ class MyDocument extends Document {
public render() { public render() {
return ( return (
<Html> <Html lang="en">
<Head> <Head>
<link rel="manifest" href="/manifest.json" /> {/* General */}
<meta charSet="UTF-8" />
<link rel="icon" href="/logo/32.png"/>
{/* Web App related */}
<link rel="manifest" href="/manifest.json" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="msapplication-starturl" content="/" />
<meta name="theme-color" content={config.colors[500]} />
{/* Open Graph / Twitter */}
<meta property="twitter:card" content="summary" /> <meta property="twitter:card" content="summary" />
<meta property="twitter:site" content="aviortheking" /> <meta property="twitter:site" content="aviortheking" />
<meta property="twitter:creator" content="aviortheking" /> <meta property="twitter:creator" content="aviortheking" />
<meta property="twitter:site:id" content="3240791182" /> <meta property="twitter:site:id" content="3240791182" />
{/* Apple Icons */}
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-touch-icon" content="/logo/512.png" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-capable" content="yes" />
</Head> </Head>
<body> <body>
<Main /> <Main />

View File

@ -17,14 +17,14 @@ export default class Error extends Component<Props, {}> {
return ( return (
<main> <main>
<Head> <Head>
<title>Pouet :D</title> <title key="title">{statusCode ? statusCode : '404'} Error - Markblog</title>
</Head> </Head>
<div className="errorContainer"> <div>
<h1>{statusCode ? statusCode : '404'}</h1> <h1>{statusCode ? statusCode : '404'}</h1>
<h2>{statusCode ? codesTexts[statusCode] : codesTexts[404]}</h2> <h2>{statusCode ? codesTexts[statusCode] : codesTexts[404]}</h2>
</div> </div>
<style jsx>{` <style jsx>{`
.errorContainer { div {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -32,10 +32,6 @@ export default class Error extends Component<Props, {}> {
height: 100% height: 100%
} }
.separator {
border: 1px solid black
}
h1 { h1 {
font-size: 250px; font-size: 250px;
margin: 10px; margin: 10px;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 303 KiB

3
public/logo-white.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="150" height="150" viewBox="0 0 150 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M72.8109 101.066L25 128.807L44.2174 84.4441L72.8109 101.066ZM79.7067 24.0024L125 128.807L45.0697 82.3519L70.2925 24.0024C71.8679 22.4526 73.4308 21.8064 74.9806 22.0652C76.556 21.7808 78.1321 22.427 79.7067 24.0024Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 390 B

3
public/logo/192.png Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:85dd3429d6868cb1acc290380a0dda48987dfcfa37909e48d7ebda96926e311f
size 4305

BIN
public/logo/192.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

3
public/logo/32.png Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:206c4992d28596d0d33418a05358dc6304c662d1dfe1aef959ca636d392cc0b7
size 717

3
public/logo/512.png Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:58e67537a793b543815d8c322c843859b8edd761f9d164454b592ceb027b088d
size 12844

BIN
public/logo/512.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cc25973b958e43be013954a256ce3f66a6c68b4852e40f8d6948d1fc12b40d7f
size 40183

View File

@ -1,14 +1,41 @@
{ {
"short_name": "Markblog", "short_name": "Markblog",
"name": "Markblog - Simple Markdown blog CMS", "name": "Markblog - Simple Markdown blog CMS",
"icons": [ "description": "A static blog generator",
], "lang": "en-US",
"icons": [{
"src": "logo/maskable_icon.png",
"type": "image/png",
"sizes": "1024x1024",
"purpose": "maskable"
}, {
"src": "logo.svg",
"type":"image/svg+xml",
"sizes":"512x512"
}, {
"src": "logo/512.webp",
"type": "image/webp",
"sizes": "512x512"
}, {
"src": "logo/512.png",
"type": "image/png",
"sizes": "512x512"
}, {
"src": "logo/192.webp",
"type": "image/webp",
"sizes": "192x192"
}, {
"src": "logo/192.png",
"type": "image/png",
"sizes": "192x192"
}],
"serviceworker": { "serviceworker": {
"src": "/service-worker.js" "src": "/service-worker.js"
}, },
"start_url": "/", "start_url": "/",
"scope": "/", "scope": "/",
"background_color": "#6200EE", "orientation": "any",
"background_color": "#FFFFFF",
"display": "standalone", "display": "standalone",
"theme_color": "#6200EE" "theme_color": "#6200EE"
} }

View File

@ -3,13 +3,14 @@
src: local('Aileron Bold'), local('Aileron-Bold'), url('/fonts/Aileron-Bold.ttf') format('truetype') src: local('Aileron Bold'), local('Aileron-Bold'), url('/fonts/Aileron-Bold.ttf') format('truetype')
font-weight: bold font-weight: bold
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
font-family: 'Aileron' font-family: 'Aileron'
src: local('Aileron Italic'), local('Aileron-Italic'), url('/fonts/Aileron-Italic.ttf') format('truetype') src: local('Aileron Italic'), local('Aileron-Italic'), url('/fonts/Aileron-Italic.ttf') format('truetype')
font-weight: normal font-weight: normal
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -17,6 +18,7 @@
src: local('Aileron Black Italic'), local('Aileron-BlackItalic'), url('/fonts/Aileron-BlackItalic.ttf') format('truetype') src: local('Aileron Black Italic'), local('Aileron-BlackItalic'), url('/fonts/Aileron-BlackItalic.ttf') format('truetype')
font-weight: 900 font-weight: 900
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -24,6 +26,7 @@
src: local('Aileron Bold Italic'), local('Aileron-BoldItalic'), url('/fonts/Aileron-BoldItalic.ttf') format('truetype') src: local('Aileron Bold Italic'), local('Aileron-BoldItalic'), url('/fonts/Aileron-BoldItalic.ttf') format('truetype')
font-weight: bold font-weight: bold
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -31,13 +34,14 @@
src: local('Aileron Light'), local('Aileron-Light'), url('/fonts/Aileron-Light.ttf') format('truetype') src: local('Aileron Light'), local('Aileron-Light'), url('/fonts/Aileron-Light.ttf') format('truetype')
font-weight: 300 font-weight: 300
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
font-family: 'Aileron' font-family: 'Aileron'
src: local('Aileron Black'), local('Aileron-Black'), url('/fonts/Aileron-Black.ttf') format('truetype') src: local('Aileron Black'), local('Aileron-Black'), url('/fonts/Aileron-Black.ttf') format('truetype')
font-weight: 900 font-weight: 900
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -45,6 +49,7 @@
src: local('Aileron Heavy Italic'), local('Aileron-HeavyItalic'), url('/fonts/Aileron-HeavyItalic.ttf') format('truetype') src: local('Aileron Heavy Italic'), local('Aileron-HeavyItalic'), url('/fonts/Aileron-HeavyItalic.ttf') format('truetype')
font-weight: 900 font-weight: 900
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -52,6 +57,7 @@
src: local('Aileron UltraLight Italic'), local('Aileron-UltraLightItalic'), url('/fonts/Aileron-UltraLightItalic.ttf') format('truetype') src: local('Aileron UltraLight Italic'), local('Aileron-UltraLightItalic'), url('/fonts/Aileron-UltraLightItalic.ttf') format('truetype')
font-weight: 200 font-weight: 200
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -59,6 +65,7 @@
src: local('Aileron Heavy'), local('Aileron-Heavy'), url('/fonts/Aileron-Heavy.ttf') format('truetype') src: local('Aileron Heavy'), local('Aileron-Heavy'), url('/fonts/Aileron-Heavy.ttf') format('truetype')
font-weight: 900 font-weight: 900
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -66,6 +73,7 @@
src: local('Aileron Thin'), local('Aileron-Thin'), url('/fonts/Aileron-Thin.ttf') format('truetype') src: local('Aileron Thin'), local('Aileron-Thin'), url('/fonts/Aileron-Thin.ttf') format('truetype')
font-weight: 100 font-weight: 100
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -73,6 +81,7 @@
src: local('Aileron UltraLight'), local('Aileron-UltraLight'), url('/fonts/Aileron-UltraLight.ttf') format('truetype') src: local('Aileron UltraLight'), local('Aileron-UltraLight'), url('/fonts/Aileron-UltraLight.ttf') format('truetype')
font-weight: 200 font-weight: 200
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -80,6 +89,7 @@
src: local('Aileron SemiBold'), local('Aileron-SemiBold'), url('/fonts/Aileron-SemiBold.ttf') format('truetype') src: local('Aileron SemiBold'), local('Aileron-SemiBold'), url('/fonts/Aileron-SemiBold.ttf') format('truetype')
font-weight: 600 font-weight: 600
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -87,6 +97,7 @@
src: local('Aileron Regular'), local('Aileron-Regular'), url('/fonts/Aileron-Regular.ttf') format('truetype') src: local('Aileron Regular'), local('Aileron-Regular'), url('/fonts/Aileron-Regular.ttf') format('truetype')
font-weight: normal font-weight: normal
font-style: normal font-style: normal
font-display: swap
@font-face @font-face
@ -94,6 +105,7 @@
src: local('Aileron Thin Italic'), local('Aileron-ThinItalic'), url('/fonts/Aileron-ThinItalic.ttf') format('truetype') src: local('Aileron Thin Italic'), local('Aileron-ThinItalic'), url('/fonts/Aileron-ThinItalic.ttf') format('truetype')
font-weight: 100 font-weight: 100
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -101,6 +113,7 @@
src: local('Aileron Light Italic'), local('Aileron-LightItalic'), url('/fonts/Aileron-LightItalic.ttf') format('truetype') src: local('Aileron Light Italic'), local('Aileron-LightItalic'), url('/fonts/Aileron-LightItalic.ttf') format('truetype')
font-weight: 300 font-weight: 300
font-style: italic font-style: italic
font-display: swap
@font-face @font-face
@ -108,3 +121,4 @@
src: local('Aileron SemiBold Italic'), local('Aileron-SemiBoldItalic'), url('/fonts/Aileron-SemiBoldItalic.ttf') format('truetype') src: local('Aileron SemiBold Italic'), local('Aileron-SemiBoldItalic'), url('/fonts/Aileron-SemiBoldItalic.ttf') format('truetype')
font-weight: 600 font-weight: 600
font-style: italic font-style: italic
font-display: swap

View File

@ -1,10 +1,10 @@
@font-face @font-face
font-family: "Blobmoji" font-family: "Blobmoji"
// TODO: find a way to use it internally // TODO: find a way to use it internally
src: local('Blobmoji'), url('/fonts/Blobmoji.ttf') format('truetype') src local('Blobmoji'), url('/fonts/Blobmoji.ttf') format('truetype')
font-weight normal font-weight normal
font-style normal font-style normal
font-display swap
.emoji .emoji
font-family: 'Blobmoji' font-family: 'Blobmoji'

View File

@ -6,6 +6,10 @@ $color = #6200EE
*:not(input) *:not(input)
display inline display inline
&:focus
// Chrome outline on focus
outline none
&.inline &.inline
display inline-block display inline-block

View File

@ -24,6 +24,8 @@
"include": [ "include": [
"next-env.d.ts", "next-env.d.ts",
"**/*.ts", "**/*.ts",
"**/*.tsx" "**/*.tsx",
"*.ts",
"sitemapGenerator.js"
] ]
} }

2231
yarn.lock

File diff suppressed because it is too large Load Diff