mirror of
https://github.com/kremalicious/blog.git
synced 2024-12-22 17:23:50 +01:00
commit
724c7df12b
@ -34,5 +34,9 @@ module.exports = {
|
||||
title: 'Tags',
|
||||
link: '/tags'
|
||||
}
|
||||
]
|
||||
],
|
||||
darkModeConfig: {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light'
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
---
|
||||
type: post
|
||||
type: link
|
||||
|
||||
title: London police afraid of photographers
|
||||
author: Matthias Kretschmann
|
||||
|
||||
linkurl: http://www.met.police.uk/campaigns/campaign_ct_2008.htm
|
||||
date: 2008-04-04 19:01:09+00:00
|
||||
|
||||
tags:
|
||||
- photography
|
||||
|
||||
redirect_from:
|
||||
- /2008/04/london-police-afraid-of-photographers/
|
||||
---
|
||||
|
||||
![London cops](../media/londonpolice.jpg)
|
||||
|
||||
<!-- more -->
|
||||
|
||||
> Thousands of people take photos every day. What if one of them seems odd? Terrorists use surveillance to help plan attacks, taking photos and making notes about security measures like the location of CCTV cameras. If you see someone doing that, we need to know. Let experienced officers decide what action to take.
|
||||
|
||||
yeah, i'm guilty. i took several photos of cctv cameras:
|
||||
[At Agentur Ahron](http://www.agentur-ahron.de/bild_db/details.php?image_id=552)
|
||||
[At Panthermedia](http://www.panthermedia.net/index2.php?page=image_preview.php&image=441619)
|
||||
Yeah, i'm guilty. I took several photos of cctv cameras.
|
||||
|
||||
And there are more in my photo archive... Guess you have no other choice than informing the London cops cause they just "need to know".
|
||||
|
||||
You can find the campaign website of the london police here:
|
||||
[Metropolitan Police 2008 Counter-Terrorism advertising campaign launched](http://www.met.police.uk/campaigns/campaign_ct_2008.htm)
|
||||
|
||||
You will be surprised what other things they are afraid of...
|
||||
|
@ -13,7 +13,7 @@ tags:
|
||||
|
||||
[![London police afraid of photographers](../media/londonpolice.jpg)](../media/londonpolice.jpg)
|
||||
|
||||
Remember [the campaign of the London police](http://www.kremalicious.com/2008/04/london-police-afraid-of-photographers/) calling all people to regard photographers as potential terrorists?
|
||||
Remember [the campaign of the London police](/london-police-afraid-of-photographers/) calling all people to regard photographers as potential terrorists?
|
||||
|
||||
Now the [PressGazette reports](http://www.pressgazette.co.uk/node/40875) that
|
||||
|
||||
|
@ -221,8 +221,7 @@ module.exports = {
|
||||
{
|
||||
resolve: 'gatsby-plugin-use-dark-mode',
|
||||
options: {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light',
|
||||
...siteConfig.darkModeConfig,
|
||||
minify: true
|
||||
}
|
||||
},
|
||||
|
@ -24,7 +24,7 @@ function getPaginationData(i, numPages, slug) {
|
||||
}
|
||||
|
||||
exports.generatePostPages = (createPage, posts) => {
|
||||
const postTemplate = path.resolve('src/templates/Post/index.tsx')
|
||||
const postTemplate = path.resolve('src/templates/Post.tsx')
|
||||
|
||||
// Create Post pages
|
||||
posts.forEach(post => {
|
||||
|
25
jest/__fixtures__/link.json
Normal file
25
jest/__fixtures__/link.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"post": {
|
||||
"html": "<p>An awesome creative idea for a blog post about Web-Design from Joshua Clanton:</p>\n<blockquote>\n<p>Leonardo Da Vinci was one of the greatest artists of the Renaissance, leaving behind a legacy that continues to inspire artists, scientists and others. Here are six things we can learn from him about web design.</p>\n</blockquote>",
|
||||
"excerpt": "An awesome creative idea for a blog post about Web-Design from Joshua Clanton: Leonardo Da Vinci was one of the greatest artists of the…",
|
||||
"frontmatter": {
|
||||
"type": "link",
|
||||
"title": "6 Web Design Tips from Leonardo da Vinci",
|
||||
"image": null,
|
||||
"toc": null,
|
||||
"author": "Matthias Kretschmann",
|
||||
"updated": null,
|
||||
"tags": ["design"],
|
||||
"linkurl": "http://designpepper.com/blog/6-web-design-tips-from-leonardo-da-vinci",
|
||||
"style": null,
|
||||
"changelog": null
|
||||
},
|
||||
"fields": {
|
||||
"slug": "/6-web-design-tips-from-leonardo-da-vinci",
|
||||
"date": "2008-04-04T18:43:05.000Z",
|
||||
"githubLink": "https://github.com/kremalicious/blog/tree/master/content/posts/2008-04-04-6-web-design-tips-from-leonardo-da-vinci.md"
|
||||
},
|
||||
"rawMarkdownBody": "\nAn awesome creative idea for a blog post about Web-Design from Joshua Clanton:\n\n> Leonardo Da Vinci was one of the greatest artists of the Renaissance, leaving behind a legacy that continues to inspire artists, scientists and others. Here are six things we can learn from him about web design.\n",
|
||||
"tableOfContents": ""
|
||||
}
|
||||
}
|
41
jest/__fixtures__/postWithMore.json
Normal file
41
jest/__fixtures__/postWithMore.json
Normal file
File diff suppressed because one or more lines are too long
4
src/@types/Site.d.ts
vendored
4
src/@types/Site.d.ts
vendored
@ -26,4 +26,8 @@ export interface Site {
|
||||
jsonfeed: string
|
||||
itemsPerPage: number
|
||||
repoContentPath: string
|
||||
darkModeConfig: {
|
||||
classNameDark: string
|
||||
classNameLight: string
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
export const fadeIn = {
|
||||
enter: {
|
||||
opacity: 1
|
||||
},
|
||||
exit: {
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
const transition = { type: 'spring' }
|
||||
|
||||
const enter = {
|
||||
y: 0,
|
||||
...transition
|
||||
}
|
||||
|
||||
export const moveInTop = {
|
||||
...enter,
|
||||
exit: {
|
||||
y: '-2rem',
|
||||
...transition
|
||||
}
|
||||
}
|
||||
|
||||
export const moveInBottom = {
|
||||
...enter,
|
||||
exit: {
|
||||
y: '2rem',
|
||||
...transition
|
||||
}
|
||||
}
|
10
src/components/molecules/Featured.test.tsx
Normal file
10
src/components/molecules/Featured.test.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Featured from './Featured'
|
||||
|
||||
describe('Featured', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(<Featured />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
16
src/components/molecules/Networks.test.tsx
Normal file
16
src/components/molecules/Networks.test.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import Networks from './Networks'
|
||||
|
||||
import meta from '../../../jest/__fixtures__/meta.json'
|
||||
|
||||
const { author, rss, jsonfeed } = meta.site.siteMetadata
|
||||
const { twitter, github } = author
|
||||
const links = [twitter, github, rss, jsonfeed, 'hello']
|
||||
|
||||
describe('Networks', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(<Networks links={links} />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
13
src/components/molecules/PostTeaser.test.tsx
Normal file
13
src/components/molecules/PostTeaser.test.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import PostTeaser from './PostTeaser'
|
||||
import post from '../../../jest/__fixtures__/post.json'
|
||||
|
||||
describe('PostTeaser', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container, rerender } = render(<PostTeaser post={post.post} />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
rerender(<PostTeaser post={post.post} toggleSearch={() => null} />)
|
||||
})
|
||||
})
|
16
src/components/molecules/RelatedPosts.test.tsx
Normal file
16
src/components/molecules/RelatedPosts.test.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import RelatedPosts from './RelatedPosts'
|
||||
|
||||
describe('RelatedPosts', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container, rerender, getByText } = render(
|
||||
<RelatedPosts tags={['hello', 'design']} />
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
fireEvent.click(getByText('Refresh'))
|
||||
|
||||
rerender(<RelatedPosts tags={['hello', 'design']} photos />)
|
||||
})
|
||||
})
|
@ -1,10 +1,8 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent, cleanup } from '@testing-library/react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import ThemeSwitch from './ThemeSwitch'
|
||||
|
||||
describe('ThemeSwitch', () => {
|
||||
afterEach(cleanup)
|
||||
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(<ThemeSwitch />)
|
||||
const switchContainer = container.querySelector('aside')
|
||||
|
@ -3,6 +3,7 @@ import Helmet from 'react-helmet'
|
||||
import useDarkMode from 'use-dark-mode'
|
||||
import styles from './ThemeSwitch.module.scss'
|
||||
import Icon from '../atoms/Icon'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
|
||||
const ThemeToggle = () => (
|
||||
<span id="toggle" className={styles.checkboxContainer} aria-live="assertive">
|
||||
@ -40,10 +41,8 @@ const HeadMarkup = ({ themeColor }: { themeColor: string }) => (
|
||||
)
|
||||
|
||||
export default function ThemeSwitch() {
|
||||
const darkMode = useDarkMode(false, {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light'
|
||||
})
|
||||
const { darkModeConfig } = useSiteMetadata()
|
||||
const darkMode = useDarkMode(false, darkModeConfig)
|
||||
const themeColor = darkMode.value ? '#1d2224' : '#e7eef4'
|
||||
|
||||
return (
|
||||
|
21
src/components/molecules/Web3Donation/InputGroup.test.tsx
Normal file
21
src/components/molecules/Web3Donation/InputGroup.test.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
|
||||
import InputGroup from './InputGroup'
|
||||
|
||||
const sendTransaction = jest.fn()
|
||||
|
||||
describe('InputGroup', () => {
|
||||
it('renders without crashing', async () => {
|
||||
const { container } = render(
|
||||
<InputGroup sendTransaction={sendTransaction} />
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
const input = container.querySelector('input')
|
||||
const button = container.querySelector('button')
|
||||
fireEvent.change(input, { target: { value: '3' } })
|
||||
fireEvent.click(button)
|
||||
expect(sendTransaction).toHaveBeenCalled()
|
||||
})
|
||||
})
|
@ -1,7 +1,19 @@
|
||||
import React from 'react'
|
||||
import testRender from '../../../jest/testRender'
|
||||
import { render, fireEvent } from '@testing-library/react'
|
||||
import Header from './Header'
|
||||
|
||||
describe('Header', () => {
|
||||
testRender(<Header />)
|
||||
it('renders correctly', () => {
|
||||
const { container, getByTitle, getByPlaceholderText } = render(
|
||||
<div id="document">
|
||||
<Header />
|
||||
</div>
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
fireEvent.click(getByTitle('Menu'))
|
||||
fireEvent.click(getByTitle('Search'))
|
||||
|
||||
const input = getByPlaceholderText('Search everything')
|
||||
fireEvent.change(input, { target: { value: 'wallpaper' } })
|
||||
})
|
||||
})
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
import styles from './PostActions.module.scss'
|
||||
import Icon from '../../components/atoms/Icon'
|
||||
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
|
||||
import styles from './Actions.module.scss'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
interface ActionProps {
|
||||
title: string
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import Changelog from '../../components/atoms/Changelog'
|
||||
import { Post } from '../../@types/Post'
|
||||
import PostToc from './PostToc'
|
||||
import Changelog from '../../atoms/Changelog'
|
||||
import { Post } from '../../../@types/Post'
|
||||
import PostToc from './Toc'
|
||||
|
||||
// Remove lead paragraph from content
|
||||
const PostContent = ({ post }: { post: Post }) => {
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import styles from './PostLead.module.scss'
|
||||
import { Post } from '../../@types/Post'
|
||||
import styles from './Lead.module.scss'
|
||||
import { Post } from '../../../@types/Post'
|
||||
|
||||
// Extract lead paragraph from content
|
||||
// Grab everything before more tag, or just first paragraph
|
@ -1,8 +1,8 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import stylesPostMore from './PostMore.module.scss'
|
||||
import styles from './PostLinkActions.module.scss'
|
||||
import Icon from '../../components/atoms/Icon'
|
||||
import stylesPostMore from './More.module.scss'
|
||||
import styles from './LinkActions.module.scss'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
const PostLinkActions = ({
|
||||
linkurl,
|
@ -1,11 +1,11 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import slugify from 'slugify'
|
||||
import Time from '../../components/atoms/Time'
|
||||
import Tag from '../../components/atoms/Tag'
|
||||
import { useSiteMetadata } from '../../hooks/use-site-metadata'
|
||||
import styles from './PostMeta.module.scss'
|
||||
import { Post } from '../../@types/Post'
|
||||
import Time from '../../atoms/Time'
|
||||
import Tag from '../../atoms/Tag'
|
||||
import { useSiteMetadata } from '../../../hooks/use-site-metadata'
|
||||
import styles from './Meta.module.scss'
|
||||
import { Post } from '../../../@types/Post'
|
||||
import shortid from 'shortid'
|
||||
|
||||
export default function PostMeta({ post }: { post: Post }) {
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import Icon from '../../components/atoms/Icon'
|
||||
import styles from './PostMore.module.scss'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import styles from './More.module.scss'
|
||||
|
||||
const PostMore = ({ to, children }: { to: string; children: string }) => (
|
||||
<Link className={styles.postMore} to={to}>
|
@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import Icon from '../../components/atoms/Icon'
|
||||
import Icon from '../../atoms/Icon'
|
||||
import styles from './PrevNext.module.scss'
|
||||
|
||||
interface Node {
|
@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'gatsby'
|
||||
import styles from './PostTitle.module.scss'
|
||||
import Icon from '../../components/atoms/Icon'
|
||||
import styles from './Title.module.scss'
|
||||
import Icon from '../../atoms/Icon'
|
||||
|
||||
export default function PostTitle({
|
||||
type,
|
@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styles from './PostToc.module.scss'
|
||||
import styles from './Toc.module.scss'
|
||||
|
||||
const PostToc = ({ tableOfContents }: { tableOfContents: string }) => {
|
||||
return (
|
12
src/helpers/wrapPageElement.test.tsx
Normal file
12
src/helpers/wrapPageElement.test.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import WrapPageElement from './wrapPageElement'
|
||||
|
||||
describe('wrapPageElement', () => {
|
||||
it('renders correctly', () => {
|
||||
const { container } = render(
|
||||
<WrapPageElement element={'Hello'} props={'hello'} />
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
@ -28,6 +28,10 @@ const query = graphql`
|
||||
jsonfeed
|
||||
itemsPerPage
|
||||
repoContentPath
|
||||
darkModeConfig {
|
||||
classNameDark
|
||||
classNameLight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
24
src/templates/Post.test.tsx
Normal file
24
src/templates/Post.test.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
import Post from './Post'
|
||||
import post from '../../jest/__fixtures__/post.json'
|
||||
import postWithMore from '../../jest/__fixtures__/postWithMore.json'
|
||||
import link from '../../jest/__fixtures__/link.json'
|
||||
|
||||
describe('Post', () => {
|
||||
const pageContext = {
|
||||
next: { title: 'hello', slug: '/hello' },
|
||||
prev: { title: 'hello2', slug: '/hello2' }
|
||||
}
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const { container, rerender } = render(
|
||||
<Post data={post} pageContext={pageContext} />
|
||||
)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
|
||||
rerender(<Post data={postWithMore} pageContext={pageContext} />)
|
||||
rerender(<Post data={link} pageContext={pageContext} />)
|
||||
})
|
||||
})
|
@ -1,19 +1,19 @@
|
||||
import React from 'react'
|
||||
import { Helmet } from 'react-helmet'
|
||||
import { graphql } from 'gatsby'
|
||||
import { Post as PostMetadata } from '../../@types/Post'
|
||||
import Exif from '../../components/atoms/Exif'
|
||||
import SEO from '../../components/atoms/SEO'
|
||||
import RelatedPosts from '../../components/molecules/RelatedPosts'
|
||||
import PostTitle from './PostTitle'
|
||||
import PostLead from './PostLead'
|
||||
import PostContent from './PostContent'
|
||||
import PostActions from './PostActions'
|
||||
import PostLinkActions from './PostLinkActions'
|
||||
import PostMeta from './PostMeta'
|
||||
import PrevNext from './PrevNext'
|
||||
import styles from './index.module.scss'
|
||||
import { Image } from '../../components/atoms/Image'
|
||||
import { Post as PostMetadata } from '../@types/Post'
|
||||
import Exif from '../components/atoms/Exif'
|
||||
import SEO from '../components/atoms/SEO'
|
||||
import RelatedPosts from '../components/molecules/RelatedPosts'
|
||||
import PostTitle from '../components/organisms/Post/Title'
|
||||
import PostLead from '../components/organisms/Post/Lead'
|
||||
import PostContent from '../components/organisms/Post/Content'
|
||||
import PostActions from '../components/organisms/Post/Actions'
|
||||
import PostLinkActions from '../components/organisms/Post/LinkActions'
|
||||
import PostMeta from '../components/organisms/Post/Meta'
|
||||
import PrevNext from '../components/organisms/Post/PrevNext'
|
||||
import styles from './Post.module.scss'
|
||||
import { Image } from '../components/atoms/Image'
|
||||
|
||||
export default function Post({
|
||||
data,
|
@ -1,17 +0,0 @@
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
|
||||
import Post from '.'
|
||||
import data from '../../../jest/__fixtures__/post.json'
|
||||
|
||||
describe('Post', () => {
|
||||
const pageContext = {
|
||||
next: { title: 'hello', slug: '/hello' },
|
||||
prev: { title: 'hello2', slug: '/hello2' }
|
||||
}
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const { container } = render(<Post data={data} pageContext={pageContext} />)
|
||||
expect(container.firstChild).toBeInTheDocument()
|
||||
})
|
||||
})
|
@ -3,11 +3,11 @@ import { Link, graphql } from 'gatsby'
|
||||
import { Post } from '../@types/Post'
|
||||
import Pagination from '../components/molecules/Pagination'
|
||||
import Featured from '../components/molecules/Featured'
|
||||
import PostTitle from './Post/PostTitle'
|
||||
import PostLead from './Post/PostLead'
|
||||
import PostContent from './Post/PostContent'
|
||||
import PostMore from './Post/PostMore'
|
||||
import PostLinkActions from './Post/PostLinkActions'
|
||||
import PostTitle from '../components/organisms/Post/Title'
|
||||
import PostLead from '../components/organisms/Post/Lead'
|
||||
import PostContent from '../components/organisms/Post/Content'
|
||||
import PostMore from '../components/organisms/Post/More'
|
||||
import PostLinkActions from '../components/organisms/Post/LinkActions'
|
||||
import SEO from '../components/atoms/SEO'
|
||||
import styles from './Posts.module.scss'
|
||||
import { Image } from '../components/atoms/Image'
|
||||
|
Loading…
Reference in New Issue
Block a user