1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2024-11-15 01:25:25 +01:00

Merge pull request #190 from kremalicious/feature/switch-dark-mode-component

feature/switch-dark-mode-component
This commit is contained in:
Matthias Kretschmann 2019-11-28 20:15:12 +01:00 committed by GitHub
commit a3331b0581
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 89 additions and 415 deletions

View File

@ -80,14 +80,11 @@ If you want to know how, have a look at the respective components:
### 💅 Theme switcher
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's local sunset and sunrise times. Uses Cloudflare's geo location HTTP header functionality.
If a visitor has set the theme manually that selection is remembered in `localStorage`, and is restored on next visit.
Includes a theme switcher which allows user to toggle between a light and a dark theme. Switching between them also happens automatically based on user's system preferences. If a visitor has set the theme manually that selection is remembered in `localStorage`, and is restored on next visit. All handled by [use-dark-mode](https://github.com/donavon/use-dark-mode)
If you want to know how, have a look at the respective components:
- [`src/components/molecules/ThemeSwitch.jsx`](src/components/molecules/ThemeSwitch.jsx)
- [`src/hooks/use-dark-mode.jsx`](src/hooks/use-dark-mode.jsx)
### 🏆 SEO component

View File

@ -71,6 +71,14 @@ module.exports = {
theme_color_in_head: false // dynamically set in ThemeSwitch
}
},
{
resolve: 'gatsby-plugin-use-dark-mode',
options: {
classNameDark: 'dark',
classNameLight: 'light',
minify: true
}
},
'gatsby-plugin-react-helmet',
'gatsby-transformer-sharp',
'gatsby-plugin-sharp',

46
package-lock.json generated
View File

@ -3683,6 +3683,11 @@
}
}
},
"@use-it/event-listener": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@use-it/event-listener/-/event-listener-0.1.3.tgz",
"integrity": "sha512-UCHkLOVU+xj3/1R8jXz8GzDTowkzfIDPESOBlVC2ndgwUSBEqiFdwCoUEs2lcGhJOOiEdmWxF+T23C5+60eEew=="
},
"@webassemblyjs/ast": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@ -11464,6 +11469,15 @@
"resolved": "https://registry.npmjs.org/gatsby-plugin-svgr/-/gatsby-plugin-svgr-2.0.2.tgz",
"integrity": "sha512-54REIMe79qFBAwpcnWHBkvEE9CKoEVkefF9rDXai0k642r91SZ4UeWFuAmsegPG+sPVub7tHfHu/2LVXK1I9kg=="
},
"gatsby-plugin-use-dark-mode": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/gatsby-plugin-use-dark-mode/-/gatsby-plugin-use-dark-mode-1.1.2.tgz",
"integrity": "sha512-qZEg4XmCgeq4M7ojxMUTFFj951QMGb95pWnxsSvb4nsTWTYSb0qeRE+hR/4rE5GIFnh/w9GrwuyMwStM7o7R6Q==",
"requires": {
"prop-types": "^15.7.2",
"terser": "^4.0.0"
}
},
"gatsby-plugin-webpack-bundle-analyser-v2": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/gatsby-plugin-webpack-bundle-analyser-v2/-/gatsby-plugin-webpack-bundle-analyser-v2-1.1.8.tgz",
@ -23463,11 +23477,6 @@
}
}
},
"suncalc": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.8.0.tgz",
"integrity": "sha1-HZiYEJVjB4dQ9JlKlZ5lTYdqy/U="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -24545,6 +24554,23 @@
"resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
"use-dark-mode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/use-dark-mode/-/use-dark-mode-2.3.1.tgz",
"integrity": "sha512-hmcdJR96tTustRQdaQwe6jMrZHnmPqXBxgy4jaQ4gsfhwajsCpjECuq9prgDe9XxMx/f9r96o2/md6O4Lwhwjg==",
"requires": {
"@use-it/event-listener": "^0.1.2",
"use-persisted-state": "^0.3.0"
}
},
"use-persisted-state": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/use-persisted-state/-/use-persisted-state-0.3.0.tgz",
"integrity": "sha512-UlWEq0JYg7NbvcRBZ1g6Bwe4SEbYfr1wr/D5mrmfCzSxXSwsPRYygGLlsxHcW58Rf7gGwRPBT23sNVvyVn4WYg==",
"requires": {
"@use-it/event-listener": "^0.1.2"
}
},
"utif": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz",
@ -25376,16 +25402,6 @@
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
},
"why-did-you-update": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/why-did-you-update/-/why-did-you-update-1.0.6.tgz",
"integrity": "sha512-XVrdHhdrPBDuSW8b/uH6DCb1/0984qv8KElpE8NZiRvWZX8nw49av577+ZyIrxSNesi6r2cQEhpxQTKFFHTj8A==",
"dev": true,
"requires": {
"lodash": "^4.17.11",
"react-fast-compare": "^2.0.3"
}
},
"wide-align": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",

View File

@ -36,6 +36,7 @@
"gatsby-plugin-sharp": "^2.3.4",
"gatsby-plugin-sitemap": "^2.2.22",
"gatsby-plugin-svgr": "^2.0.2",
"gatsby-plugin-use-dark-mode": "^1.1.2",
"gatsby-plugin-webpack-size": "^1.0.0",
"gatsby-source-filesystem": "^2.1.39",
"gatsby-transformer-json": "^2.2.20",
@ -55,7 +56,7 @@
"remark-parse": "^7.0.2",
"remark-react": "^6.0.0",
"shortid": "^2.2.15",
"suncalc": "^1.8.0",
"use-dark-mode": "^2.3.1",
"vcf": "^2.0.6"
},
"devDependencies": {
@ -92,8 +93,7 @@
"slugify": "^1.3.6",
"stylelint": "^12.0.0",
"stylelint-config-css-modules": "^2.1.0",
"stylelint-config-standard": "^19.0.0",
"why-did-you-update": "^1.0.6"
"stylelint-config-standard": "^19.0.0"
},
"browserslist": [
">0.2%",

View File

@ -11,11 +11,11 @@ import styles from './Layout.module.scss'
import { useMeta } from '../hooks/use-meta'
// https://github.com/welldone-software/why-did-you-render
// if (process.env.NODE_ENV !== 'production') {
// // eslint-disable-next-line
// const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.min.js')
// whyDidYouRender(React)
// }
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line
const whyDidYouRender = require('@welldone-software/why-did-you-render/dist/no-classes-transpile/umd/whyDidYouRender.min.js')
whyDidYouRender(React)
}
Layout.propTypes = {
children: PropTypes.any.isRequired,

View File

@ -1,4 +1,4 @@
import React from 'react'
import React, { memo } from 'react'
import PropTypes from 'prop-types'
// https://featherstyles.com
@ -27,7 +27,7 @@ import {
import { ReactComponent as Dribbble } from '../../images/dribbble.svg'
import styles from './Icon.module.scss'
const Icon = ({ name, ...props }) => {
const Icon = memo(({ name, ...props }) => {
const components = {
Dribbble,
Email: Mail,
@ -63,7 +63,9 @@ const Icon = ({ name, ...props }) => {
if (!IconMapped) return null
return <IconMapped className={styles.icon} {...props} />
}
})
Icon.displayName = 'Icon'
Icon.propTypes = {
name: PropTypes.string.isRequired

View File

@ -1,23 +1,25 @@
import React, { memo, useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import useDarkMode from '../../hooks/use-dark-mode'
import useDarkMode from 'use-dark-mode'
import Icon from '../atoms/Icon'
import styles from './ThemeSwitch.module.scss'
const ThemeToggle = ({ dark }) => (
const ThemeToggle = memo(({ dark }) => (
<span id="toggle" className={styles.checkboxContainer} aria-live="assertive">
<Icon name="Sun" className={!dark ? null : 'active'} />
<span className={styles.checkboxFake} />
<Icon name="Moon" className={dark ? 'active' : null} />
</span>
)
))
ThemeToggle.displayName = 'ThemeToggle'
ThemeToggle.propTypes = {
dark: PropTypes.bool.isRequired
}
const ThemeToggleInput = ({ dark, toggleDark }) => (
const ThemeToggleInput = memo(({ dark, toggleDark }) => (
<input
onChange={() => toggleDark()}
type="checkbox"
@ -26,36 +28,52 @@ const ThemeToggleInput = ({ dark, toggleDark }) => (
aria-describedby="toggle"
checked={dark}
/>
)
))
ThemeToggleInput.displayName = 'ThemeToggleInput'
ThemeToggleInput.propTypes = {
dark: PropTypes.bool.isRequired,
toggleDark: PropTypes.func.isRequired
}
const HeadItems = ({ bodyClass, themeColor }) => (
<Helmet>
<body className={bodyClass} />
<meta name="theme-color" content={themeColor} />
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
</Helmet>
)
HeadItems.propTypes = {
bodyClass: PropTypes.string.isRequired,
themeColor: PropTypes.string.isRequired
}
function ThemeSwitch() {
const { darkMode, toggleDark } = useDarkMode()
const { value, toggle } = useDarkMode(false, {
classNameDark: 'dark',
classNameLight: 'light'
})
const [themeColor, setThemeColor] = useState()
const [bodyClass, setBodyClass] = useState()
useEffect(() => {
darkMode ? setThemeColor('#1d2224') : setThemeColor('#e7eef4')
}, [darkMode])
setBodyClass(value ? 'dark' : null)
setThemeColor(value ? '#1d2224' : '#e7eef4')
}, [value])
return (
<>
<Helmet>
<body className={darkMode ? 'dark' : null} />
<meta name="theme-color" content={themeColor} />
<meta
name="apple-mobile-web-app-status-bar-style"
content="black-translucent"
/>
</Helmet>
<HeadItems themeColor={themeColor} bodyClass={bodyClass} />
<aside className={styles.themeSwitch}>
<label className={styles.checkbox}>
<span className={styles.label}>Toggle Night Mode</span>
<ThemeToggleInput dark={darkMode} toggleDark={toggleDark} />
<ThemeToggle dark={darkMode} />
<ThemeToggleInput dark={value} toggleDark={toggle} />
<ThemeToggle dark={value} />
</label>
</aside>
</>

View File

@ -1,32 +0,0 @@
import { useState, useEffect } from 'react'
import { getLocationTimes } from '../utils/getLocationTimes'
import { getCountry } from '../utils/getCountry'
export default function useDarkMode() {
const store = typeof localStorage === 'undefined' ? null : localStorage
const darkLocalStorage = store && store.getItem('darkMode')
const [darkMode, setDarkMode] = useState(false)
useEffect(() => {
darkLocalStorage
? darkLocalStorage === 'true'
? setDarkMode(true)
: setDarkMode(false)
: checkTimes()
async function checkTimes() {
const geolocation = await getCountry()
const { sunset, sunrise } = getLocationTimes(geolocation)
const now = new Date().getHours()
const weWantItDarkTimes = now >= sunset || now <= sunrise
weWantItDarkTimes && setDarkMode(true)
}
}, [darkLocalStorage, darkMode])
function toggleDark() {
setDarkMode(!darkMode)
store && store.setItem('darkMode', !darkMode)
}
return { darkMode, toggleDark }
}

View File

@ -1,242 +0,0 @@
{
"ad": ["42.5000", "1.5000"],
"ae": ["24.0000", "54.0000"],
"af": ["33.0000", "65.0000"],
"ag": ["17.0500", "-61.8000"],
"ai": ["18.2500", "-63.1667"],
"al": ["41.0000", "20.0000"],
"am": ["40.0000", "45.0000"],
"an": ["12.2500", "-68.7500"],
"ao": ["-12.5000", "18.5000"],
"ap": ["35.0000", "105.0000"],
"aq": ["-90.0000", "0.0000"],
"ar": ["-34.0000", "-64.0000"],
"as": ["-14.3333", "-170.0000"],
"at": ["47.3333", "13.3333"],
"au": ["-27.0000", "133.0000"],
"aw": ["12.5000", "-69.9667"],
"az": ["40.5000", "47.5000"],
"ba": ["44.0000", "18.0000"],
"bb": ["13.1667", "-59.5333"],
"bd": ["24.0000", "90.0000"],
"be": ["50.8333", "4.0000"],
"bf": ["13.0000", "-2.0000"],
"bg": ["43.0000", "25.0000"],
"bh": ["26.0000", "50.5500"],
"bi": ["-3.5000", "30.0000"],
"bj": ["9.5000", "2.2500"],
"bm": ["32.3333", "-64.7500"],
"bn": ["4.5000", "114.6667"],
"bo": ["-17.0000", "-65.0000"],
"br": ["-10.0000", "-55.0000"],
"bs": ["24.2500", "-76.0000"],
"bt": ["27.5000", "90.5000"],
"bv": ["-54.4333", "3.4000"],
"bw": ["-22.0000", "24.0000"],
"by": ["53.0000", "28.0000"],
"bz": ["17.2500", "-88.7500"],
"ca": ["60.0000", "-95.0000"],
"cc": ["-12.5000", "96.8333"],
"cd": ["0.0000", "25.0000"],
"cf": ["7.0000", "21.0000"],
"cg": ["-1.0000", "15.0000"],
"ch": ["47.0000", "8.0000"],
"ci": ["8.0000", "-5.0000"],
"ck": ["-21.2333", "-159.7667"],
"cl": ["-30.0000", "-71.0000"],
"cm": ["6.0000", "12.0000"],
"cn": ["35.0000", "105.0000"],
"co": ["4.0000", "-72.0000"],
"cr": ["10.0000", "-84.0000"],
"cu": ["21.5000", "-80.0000"],
"cv": ["16.0000", "-24.0000"],
"cx": ["-10.5000", "105.6667"],
"cy": ["35.0000", "33.0000"],
"cz": ["49.7500", "15.5000"],
"de": ["51.0000", "9.0000"],
"dj": ["11.5000", "43.0000"],
"dk": ["56.0000", "10.0000"],
"dm": ["15.4167", "-61.3333"],
"do": ["19.0000", "-70.6667"],
"dz": ["28.0000", "3.0000"],
"ec": ["-2.0000", "-77.5000"],
"ee": ["59.0000", "26.0000"],
"eg": ["27.0000", "30.0000"],
"eh": ["24.5000", "-13.0000"],
"er": ["15.0000", "39.0000"],
"es": ["40.0000", "-4.0000"],
"et": ["8.0000", "38.0000"],
"eu": ["47.0000", "8.0000"],
"fi": ["64.0000", "26.0000"],
"fj": ["-18.0000", "175.0000"],
"fk": ["-51.7500", "-59.0000"],
"fm": ["6.9167", "158.2500"],
"fo": ["62.0000", "-7.0000"],
"fr": ["46.0000", "2.0000"],
"ga": ["-1.0000", "11.7500"],
"gb": ["54.0000", "-2.0000"],
"gd": ["12.1167", "-61.6667"],
"ge": ["42.0000", "43.5000"],
"gf": ["4.0000", "-53.0000"],
"gh": ["8.0000", "-2.0000"],
"gi": ["36.1833", "-5.3667"],
"gl": ["72.0000", "-40.0000"],
"gm": ["13.4667", "-16.5667"],
"gn": ["11.0000", "-10.0000"],
"gp": ["16.2500", "-61.5833"],
"gq": ["2.0000", "10.0000"],
"gr": ["39.0000", "22.0000"],
"gs": ["-54.5000", "-37.0000"],
"gt": ["15.5000", "-90.2500"],
"gu": ["13.4667", "144.7833"],
"gw": ["12.0000", "-15.0000"],
"gy": ["5.0000", "-59.0000"],
"hk": ["22.2500", "114.1667"],
"hm": ["-53.1000", "72.5167"],
"hn": ["15.0000", "-86.5000"],
"hr": ["45.1667", "15.5000"],
"ht": ["19.0000", "-72.4167"],
"hu": ["47.0000", "20.0000"],
"id": ["-5.0000", "120.0000"],
"ie": ["53.0000", "-8.0000"],
"il": ["31.5000", "34.7500"],
"in": ["20.0000", "77.0000"],
"io": ["-6.0000", "71.5000"],
"iq": ["33.0000", "44.0000"],
"ir": ["32.0000", "53.0000"],
"is": ["65.0000", "-18.0000"],
"it": ["42.8333", "12.8333"],
"jm": ["18.2500", "-77.5000"],
"jo": ["31.0000", "36.0000"],
"jp": ["36.0000", "138.0000"],
"ke": ["1.0000", "38.0000"],
"kg": ["41.0000", "75.0000"],
"kh": ["13.0000", "105.0000"],
"ki": ["1.4167", "173.0000"],
"km": ["-12.1667", "44.2500"],
"kn": ["17.3333", "-62.7500"],
"kp": ["40.0000", "127.0000"],
"kr": ["37.0000", "127.5000"],
"kw": ["29.3375", "47.6581"],
"ky": ["19.5000", "-80.5000"],
"kz": ["48.0000", "68.0000"],
"la": ["18.0000", "105.0000"],
"lb": ["33.8333", "35.8333"],
"lc": ["13.8833", "-61.1333"],
"li": ["47.1667", "9.5333"],
"lk": ["7.0000", "81.0000"],
"lr": ["6.5000", "-9.5000"],
"ls": ["-29.5000", "28.5000"],
"lt": ["56.0000", "24.0000"],
"lu": ["49.7500", "6.1667"],
"lv": ["57.0000", "25.0000"],
"ly": ["25.0000", "17.0000"],
"ma": ["32.0000", "-5.0000"],
"mc": ["43.7333", "7.4000"],
"md": ["47.0000", "29.0000"],
"me": ["42.0000", "19.0000"],
"mg": ["-20.0000", "47.0000"],
"mh": ["9.0000", "168.0000"],
"mk": ["41.8333", "22.0000"],
"ml": ["17.0000", "-4.0000"],
"mm": ["22.0000", "98.0000"],
"mn": ["46.0000", "105.0000"],
"mo": ["22.1667", "113.5500"],
"mp": ["15.2000", "145.7500"],
"mq": ["14.6667", "-61.0000"],
"mr": ["20.0000", "-12.0000"],
"ms": ["16.7500", "-62.2000"],
"mt": ["35.8333", "14.5833"],
"mu": ["-20.2833", "57.5500"],
"mv": ["3.2500", "73.0000"],
"mw": ["-13.5000", "34.0000"],
"mx": ["23.0000", "-102.0000"],
"my": ["2.5000", "112.5000"],
"mz": ["-18.2500", "35.0000"],
"na": ["-22.0000", "17.0000"],
"nc": ["-21.5000", "165.5000"],
"ne": ["16.0000", "8.0000"],
"nf": ["-29.0333", "167.9500"],
"ng": ["10.0000", "8.0000"],
"ni": ["13.0000", "-85.0000"],
"nl": ["52.5000", "5.7500"],
"no": ["62.0000", "10.0000"],
"np": ["28.0000", "84.0000"],
"nr": ["-0.5333", "166.9167"],
"nu": ["-19.0333", "-169.8667"],
"nz": ["-41.0000", "174.0000"],
"om": ["21.0000", "57.0000"],
"pa": ["9.0000", "-80.0000"],
"pe": ["-10.0000", "-76.0000"],
"pf": ["-15.0000", "-140.0000"],
"pg": ["-6.0000", "147.0000"],
"ph": ["13.0000", "122.0000"],
"pk": ["30.0000", "70.0000"],
"pl": ["52.0000", "20.0000"],
"pm": ["46.8333", "-56.3333"],
"pr": ["18.2500", "-66.5000"],
"ps": ["32.0000", "35.2500"],
"pt": ["39.5000", "-8.0000"],
"pw": ["7.5000", "134.5000"],
"py": ["-23.0000", "-58.0000"],
"qa": ["25.5000", "51.2500"],
"re": ["-21.1000", "55.6000"],
"ro": ["46.0000", "25.0000"],
"rs": ["44.0000", "21.0000"],
"ru": ["60.0000", "100.0000"],
"rw": ["-2.0000", "30.0000"],
"sa": ["25.0000", "45.0000"],
"sb": ["-8.0000", "159.0000"],
"sc": ["-4.5833", "55.6667"],
"sd": ["15.0000", "30.0000"],
"se": ["62.0000", "15.0000"],
"sg": ["1.3667", "103.8000"],
"sh": ["-15.9333", "-5.7000"],
"si": ["46.0000", "15.0000"],
"sj": ["78.0000", "20.0000"],
"sk": ["48.6667", "19.5000"],
"sl": ["8.5000", "-11.5000"],
"sm": ["43.7667", "12.4167"],
"sn": ["14.0000", "-14.0000"],
"so": ["10.0000", "49.0000"],
"sr": ["4.0000", "-56.0000"],
"st": ["1.0000", "7.0000"],
"sv": ["13.8333", "-88.9167"],
"sy": ["35.0000", "38.0000"],
"sz": ["-26.5000", "31.5000"],
"tc": ["21.7500", "-71.5833"],
"td": ["15.0000", "19.0000"],
"tf": ["-43.0000", "67.0000"],
"tg": ["8.0000", "1.1667"],
"th": ["15.0000", "100.0000"],
"tj": ["39.0000", "71.0000"],
"tk": ["-9.0000", "-172.0000"],
"tm": ["40.0000", "60.0000"],
"tn": ["34.0000", "9.0000"],
"to": ["-20.0000", "-175.0000"],
"tr": ["39.0000", "35.0000"],
"tt": ["11.0000", "-61.0000"],
"tv": ["-8.0000", "178.0000"],
"tw": ["23.5000", "121.0000"],
"tz": ["-6.0000", "35.0000"],
"ua": ["49.0000", "32.0000"],
"ug": ["1.0000", "32.0000"],
"um": ["19.2833", "166.6000"],
"us": ["38.0000", "-97.0000"],
"uy": ["-33.0000", "-56.0000"],
"uz": ["41.0000", "64.0000"],
"va": ["41.9000", "12.4500"],
"vc": ["13.2500", "-61.2000"],
"ve": ["8.0000", "-66.0000"],
"vg": ["18.5000", "-64.5000"],
"vi": ["18.3333", "-64.8333"],
"vn": ["16.0000", "106.0000"],
"vu": ["-16.0000", "167.0000"],
"wf": ["-13.3000", "-176.2000"],
"ws": ["-13.5833", "-172.3333"],
"ye": ["15.0000", "48.0000"],
"yt": ["-12.8333", "45.1667"],
"za": ["-29.0000", "24.0000"],
"zm": ["-15.0000", "30.0000"],
"zw": ["-20.0000", "30.0000"]
}

View File

@ -1,28 +0,0 @@
//
// Get user location from Cloudflare's geo location HTTP header
//
// @returns country: string
//
export const getCountry = async () => {
try {
const data = await fetch('/cdn-cgi/trace?no-cache=1')
const text = await data.text().replace(/ /g, '')
const lines = text.split('\n')
let keyValue
let trace = []
await lines.forEach(line => {
keyValue = line.split('=')
trace[keyValue[0]] = decodeURIComponent(keyValue[1] || '')
})
const country = trace['loc']
if (country && country !== 'XX') {
return country
}
} catch (error) {
return null // fail silently
}
}

View File

@ -1,31 +0,0 @@
import { getCountry } from './getCountry'
const mockFetch = data =>
jest.fn().mockImplementationOnce(() =>
Promise.resolve({
ok: true,
Id: '123',
text: () => data
// json: () => data
})
)
describe('getCountry', () => {
it('fetches and returns correct value', async () => {
global.fetch = mockFetch('loc=DE')
const country = await getCountry()
expect(global.fetch).toHaveBeenCalledTimes(1)
expect(global.fetch).toHaveBeenCalledWith('/cdn-cgi/trace?no-cache=1')
expect(country).toBe('DE')
})
it('returns nothing when XX country', async () => {
global.fetch = mockFetch('loc=XX')
const country = await getCountry()
expect(global.fetch).toHaveBeenCalledTimes(1)
expect(global.fetch).toHaveBeenCalledWith('/cdn-cgi/trace?no-cache=1')
expect(country).toBe(undefined)
})
})

View File

@ -1,25 +0,0 @@
import SunCalc from 'suncalc'
import countrycodes from './countrycode-latlong.json'
//
// All the checks to see if we should go dark or light
//
export const getLocationTimes = location => {
// fallback times, in hours
let sunrise = 7
let sunset = 19
// times based on detected country code
if (location && location !== 'XX' && location !== 'T1') {
const country = location.toLowerCase()
const times = SunCalc.getTimes(
new Date(),
countrycodes[country][0],
countrycodes[country][1]
)
sunrise = times.sunrise.getHours()
sunset = times.sunset.getHours()
}
return { sunrise, sunset }
}

View File

@ -1,9 +0,0 @@
import { getLocationTimes } from './getLocationTimes'
describe('getLocationTimes', () => {
it('returns values', async () => {
const { sunset, sunrise } = await getLocationTimes('DE')
expect(sunset).toBeDefined()
expect(sunrise).toBeDefined()
})
})