Skip to content

Commit f34c2f8

Browse files
committedNov 22, 2020
Lint: use Eslint to format all code
1 parent e3733ab commit f34c2f8

20 files changed

+676
-444
lines changed
 

‎.editorconfig

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true
11+
12+
[*.md]
13+
trim_trailing_whitespace = false
14+
15+
[Makefile]
16+
indent_style = tab

‎.eslintrc.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module.exports = {
2+
"parser": "babel-eslint",
3+
"env": {
4+
"browser": true,
5+
"es2021": true
6+
},
7+
"extends": "plugin:react/recommended",
8+
"parserOptions": {
9+
"ecmaFeatures": {
10+
"experimentalObjectRestSpread": true,
11+
"experimentalDecorators": true,
12+
"jsx": true
13+
},
14+
"ecmaVersion": 12,
15+
"sourceType": "module"
16+
},
17+
"plugins": [
18+
"prettier",
19+
"react"
20+
],
21+
"rules": {
22+
}
23+
};

‎.gitignore

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/npm-debug.log*
6+
/yarn-error.log
7+
/yarn.lock
8+
/package-lock.json
9+
10+
# production
11+
/dist
12+
13+
# misc
14+
.DS_Store
15+
16+
# umi
17+
/src/.umi
18+
/src/.umi-production
19+
/src/.umi-test
20+
/.env.local

‎.prettierignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
**/*.md
2+
**/*.svg
3+
**/*.ejs
4+
**/*.html
5+
package.json
6+
.umi
7+
.umi-production
8+
.umi-test

‎.prettierrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"singleQuote": true,
3+
"trailingComma": "all",
4+
"printWidth": 80,
5+
"overrides": [
6+
{
7+
"files": ".prettierrc",
8+
"options": { "parser": "json" }
9+
}
10+
]
11+
}

‎.umirc.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { defineConfig } from 'umi';
2+
3+
export default defineConfig({
4+
nodeModulesTransform: {
5+
type: 'none',
6+
},
7+
routes: [
8+
{ path: '/', component: '@/pages/index' },
9+
],
10+
proxy: {
11+
'/receptionist': {
12+
'target': 'http://localhost:3030/',
13+
'changeOrigin': true,
14+
}
15+
},
16+
});

‎package.json

+16-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"test": "umi-test",
99
"test:coverage": "umi-test --coverage",
1010
"push": "npm run build && scp -rp ./dist/* ubuntu@de.pano.today:~/pano/react",
11-
"lint": "eslint src/. test/. --config .eslintrc.json --fix"
11+
"lint": "eslint --ext .js --ext .jsx src",
12+
"format": "prettier-eslint --write %INIT_CWD%/src/**/*.{js,jsx}"
1213
},
1314
"gitHooks": {
1415
"pre-commit": "lint-staged"
@@ -38,7 +39,19 @@
3839
"react-wordcloud": "^1.2.7",
3940
"semantic-ui-css": "^2.4.1",
4041
"semantic-ui-react": "^2.0.1",
41-
"umi": "^3.2.27",
42+
"umi": "^3.2.28",
4243
"yorkie": "^2.0.0"
44+
},
45+
"__npminstall_done": false,
46+
"devDependencies": {
47+
"babel-eslint": "^10.1.0",
48+
"eslint": "^7.14.0",
49+
"eslint-config-prettier": "^6.15.0",
50+
"eslint-plugin-import": "^2.22.1",
51+
"eslint-plugin-prettier": "^3.1.4",
52+
"eslint-plugin-react": "^7.21.5",
53+
"prettier": "^1.19.1",
54+
"prettier-eslint": "^12.0.0",
55+
"prettier-eslint-cli": "^5.0.0"
4356
}
44-
}
57+
}

‎src/components/Calendar.js

+22-18
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
1-
import React, { Component } from 'react'
2-
import { Segment, Card, Progress, Header, Grid, Image, Button, Popup, Container } from 'semantic-ui-react'
1+
import React, { Component } from 'react';
2+
import {
3+
Segment,
4+
Card,
5+
Progress,
6+
Header,
7+
Grid,
8+
Image,
9+
Button,
10+
Popup,
11+
Container,
12+
} from 'semantic-ui-react';
313
import Clock from 'react-live-clock';
4-
import WikiNews from '../components/WikiNews'
14+
import WikiNews from '../components/WikiNews';
515

616
export default function TextClock() {
7-
const getTimezone = () => Intl.DateTimeFormat().resolvedOptions().timeZone
17+
const getTimezone = () => Intl.DateTimeFormat().resolvedOptions().timeZone;
818

9-
const timezone = getTimezone()
19+
const timezone = getTimezone();
1020
return (
11-
<Grid
12-
centered
13-
fluid
14-
>
21+
<Grid centered fluid>
1522
<Grid.Column width={2} floated="right">
16-
1723
<Popup
18-
flowing hoverable position="bottom right"
24+
flowing
25+
hoverable
26+
position="bottom right"
1927
trigger={
2028
<Segment textAlign="center">
2129
<Header>
22-
<Clock
23-
format="MMM D, YYYY"
24-
timezone={timezone}
25-
/>
30+
<Clock format="MMM D, YYYY" timezone={timezone} />
2631
</Header>
2732
</Segment>
2833
}
2934
>
3035
<WikiNews />
3136
</Popup>
32-
3337
</Grid.Column>
3438
</Grid>
35-
)
36-
}
39+
);
40+
}

‎src/components/Quote.js

+20-14
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
1+
/* eslint-disable react/prop-types */
12
import { connect } from 'dva';
23
import React, { Component } from 'react';
3-
import { Grid, Header, Icon } from "semantic-ui-react";
4+
import { Grid, Header, Icon } from 'semantic-ui-react';
5+
import genColor from '../utils/genColor';
46
import './Quote.css';
5-
import genColor from '../utils/genColor'
67

78
@connect(({ artwork }) => ({
8-
artwork
9+
artwork,
910
}))
10-
export default class Quote extends Component {
11+
class Quote extends Component {
1112
render() {
12-
console.log(this.props)
13+
console.log(this.props);
1314
return (
14-
<Grid container textAlign="justified" columns={2} >
15-
<Grid.Row textAlign='center'>
16-
<Grid.Column width={3} textAlign='right'>
15+
<Grid container textAlign="justified" columns={2}>
16+
<Grid.Row textAlign="center">
17+
<Grid.Column width={3} textAlign="right">
1718
<Icon name="quote left" size="massive" />
1819
</Grid.Column>
19-
<Grid.Column width={13} textAlign='left'>
20+
<Grid.Column width={13} textAlign="left">
2021
<Header size="huge">
2122
<Header.Content>
2223
<p className="quote-content">
2324
{this.props.artwork.quoteContent}
24-
<Icon className="back-quotation-mark-fix" name="quote right" size="tiny" />
25+
<Icon
26+
className="back-quotation-mark-fix"
27+
name="quote right"
28+
size="tiny"
29+
/>
2530
</p>
26-
<Header color={genColor()} size='small' textAlign='right'>
31+
<Header color={genColor()} size="small" textAlign="right">
2732
-&nbsp;
2833
{this.props.artwork.quoteSpeaker}
2934
</Header>
30-
3135
</Header.Content>
3236
</Header>
3337
</Grid.Column>
3438
</Grid.Row>
3539
</Grid>
36-
)
40+
);
3741
}
38-
}
42+
}
43+
44+
export default Quote;

‎src/components/Search.js

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
import React, { Component } from 'react'
2-
import { Icon, Form, Grid, Input, Image, Dropdown, Transition, Popup } from 'semantic-ui-react'
1+
import React, { Component } from 'react';
2+
import {
3+
Icon,
4+
Form,
5+
Grid,
6+
Input,
7+
Image,
8+
Dropdown,
9+
Transition,
10+
Popup,
11+
} from 'semantic-ui-react';
312

413
export default function Search(props) {
5-
const p = props
6-
const s = p.hpState
14+
const p = props;
15+
const s = p.hpState;
716
return (
817
<Grid centered fluid>
918
<Grid.Row>
@@ -13,11 +22,9 @@ export default function Search(props) {
1322
</Grid.Row>
1423
<Grid.Row>
1524
<Grid.Column width={8}>
16-
<Form
17-
onSubmit={p.formSubmit}
18-
>
25+
<Form onSubmit={p.formSubmit}>
1926
<Input
20-
placeholder='All engines, one Pano.'
27+
placeholder="All engines, one Pano."
2128
type="input"
2229
action="Search"
2330
fluid
@@ -28,16 +35,16 @@ export default function Search(props) {
2835
</Grid.Column>
2936
</Grid.Row>
3037
</Grid>
31-
)
38+
);
3239
}
3340

3441
function LogoIcon(props) {
35-
const p = props
42+
const p = props;
3643
return (
3744
<Transition visible={p.vis} duration={200} animation="pulse">
3845
<Image>
3946
<Icon name={p.name} size="massive" color="blue" />
4047
</Image>
4148
</Transition>
42-
)
43-
}
49+
);
50+
}

‎src/components/TopHeader.js

+50-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
/* eslint-disable react/no-unescaped-entities */
12
import React from 'react';
2-
import { Button, Divider, Grid, Header, Icon, Label, Modal, Segment } from 'semantic-ui-react';
3+
import {
4+
Button,
5+
Grid,
6+
Header,
7+
Icon,
8+
Label,
9+
Modal,
10+
Segment,
11+
} from 'semantic-ui-react';
312
import genColor from '../utils/genColor';
413
import './TopHeader.css';
514

@@ -11,10 +20,17 @@ export default function TopHeader() {
1120
// <Sticky context={contextRef} pushing>
1221
<div className="top-header">
1322
<Segment>
14-
<Grid verticalAlign='middle'>
23+
<Grid verticalAlign="middle">
1524
<Grid.Column floated="left" width={4} textAlign="left">
1625
<Button.Group>
17-
<Button labelPosition='left' as='a' href='http://de.pano.today/' icon='star' content='PANO' color={genColor()}/>
26+
<Button
27+
labelPosition="left"
28+
as="a"
29+
href="http://de.pano.today/"
30+
icon="star"
31+
content="PANO"
32+
color={genColor()}
33+
/>
1834
<ReuseWelcome />
1935
</Button.Group>
2036
</Grid.Column>
@@ -30,28 +46,49 @@ export default function TopHeader() {
3046
}
3147

3248
function ReuseWelcome() {
33-
const [open, setOpen] = React.useState(false)
49+
const [open, setOpen] = React.useState(false);
3450
return (
3551
<Modal
3652
onClose={() => setOpen(false)}
3753
onOpen={() => setOpen(true)}
3854
open={open}
39-
trigger={<Button size='tiny' icon><Icon name='info' /></Button>}
55+
trigger={
56+
<Button size="tiny" icon>
57+
<Icon name="info" />
58+
</Button>
59+
}
4060
>
4161
<Modal.Header>Welcome to Pano!</Modal.Header>
4262
<Modal.Content image>
43-
<Icon name='star outline' size='massive' color={genColor()} />
63+
<Icon name="star outline" size="massive" color={genColor()} />
4464
<Modal.Description>
45-
<Header color='grey'>A start panel for web browsing, a panorama of inspiration.</Header>
65+
<Header color="grey">
66+
A start panel for web browsing, a panorama of inspiration.
67+
</Header>
68+
<p>
69+
Pano is a personal project by BedrockDigger, aka Estel, aimed at a
70+
better start-off for daily browsing.
71+
</p>
4672
<p>
47-
Pano is a personal project by BedrockDigger, aka Estel, aimed at a better start-off for daily browsing.
73+
Functionalities here are limited but carefully cherry-picked, as to
74+
provide a clean experience. No more clever instructions are needed,
75+
because you're now able to explore Pano with your own eyes.
4876
</p>
4977
<p>
50-
Functionalities here are limited but carefully cherry-picked, as to provide a clean experience.
51-
No more clever instructions are needed, because you're now able to explore Pano with your own eyes.
78+
Pano doesn't steal information from you. Check the code if you're
79+
want to be sure about that.
80+
</p>
81+
<p>
82+
Code for the frontend and backend of Pano are both licensed under
83+
the MIT license, which is available{' '}
84+
<a
85+
href="https://github.com/BedrockDigger/pano-react-app"
86+
target="_blank _noreferrer"
87+
>
88+
here
89+
</a>
90+
.
5291
</p>
53-
<p>Pano doesn't steal information from you. Check the code if you're want to be sure about that.</p>
54-
<p>Code for the frontend and backend of Pano are both licensed under the MIT license, which is available <a href='https://github.com/BedrockDigger/pano-react-app' target='_blank'>here</a>.</p>
5592
</Modal.Description>
5693
</Modal.Content>
5794
<Modal.Actions>
@@ -60,5 +97,5 @@ function ReuseWelcome() {
6097
</Button>
6198
</Modal.Actions>
6299
</Modal>
63-
)
100+
);
64101
}

‎src/components/WelcomeModal.js

+31-13
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import React from 'react'
2-
import { Header, Icon, Image, Modal, Button, Grid } from 'semantic-ui-react'
3-
import genColor from '../utils/genColor'
1+
/* eslint-disable react/no-unescaped-entities */
2+
import React from 'react';
3+
import { Button, Header, Icon, Modal } from 'semantic-ui-react';
4+
import genColor from '../utils/genColor';
45

56
export default function Welcome() {
6-
const [open, setOpen] = React.useState(true)
7+
const [open, setOpen] = React.useState(true);
78
return (
89
<Modal
910
onClose={() => setOpen(false)}
@@ -12,18 +13,35 @@ export default function Welcome() {
1213
>
1314
<Modal.Header>Welcome to Pano!</Modal.Header>
1415
<Modal.Content image>
15-
<Icon name='star outline' size='massive' color={genColor()} />
16+
<Icon name="star outline" size="massive" color={genColor()} />
1617
<Modal.Description>
17-
<Header color='grey'>A start panel for web browsing, a panorama of inspiration.</Header>
18+
<Header color="grey">
19+
A start panel for web browsing, a panorama of inspiration.
20+
</Header>
1821
<p>
19-
Pano is a personal project by BedrockDigger, aka Estel, aimed at a better start-off for daily browsing.
22+
Pano is a personal project by BedrockDigger, aka Estel, aimed at a
23+
better start-off for daily browsing.
2024
</p>
2125
<p>
22-
Functionalities here are limited but carefully cherry-picked, as to provide a clean experience.
23-
No more clever instructions are needed, because you're now able to explore Pano with your own eyes.
26+
Functionalities here are limited but carefully cherry-picked, as to
27+
provide a clean experience. No more clever instructions are needed,
28+
because you're now able to explore Pano with your own eyes.
29+
</p>
30+
<p>
31+
Pano doesn't steal information from you. Check the code if you're
32+
want to be sure about that.
33+
</p>
34+
<p>
35+
Code for the frontend and backend of Pano are both licensed under
36+
the MIT license, which is available{' '}
37+
<a
38+
href="https://github.com/BedrockDigger/pano-react-app"
39+
target="_blank _noreferrer"
40+
>
41+
here
42+
</a>
43+
.
2444
</p>
25-
<p>Pano doesn't steal information from you. Check the code if you're want to be sure about that.</p>
26-
<p>Code for the frontend and backend of Pano are both licensed under the MIT license, which is available <a href='https://github.com/BedrockDigger/pano-react-app' target='_blank'>here</a>.</p>
2745
</Modal.Description>
2846
</Modal.Content>
2947
<Modal.Actions>
@@ -32,5 +50,5 @@ export default function Welcome() {
3250
</Button>
3351
</Modal.Actions>
3452
</Modal>
35-
)
36-
}
53+
);
54+
}

‎src/components/WikiNews.js

+59-69
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,77 @@
1-
import React, { Component } from 'react'
2-
import { Feed, Placeholder, Grid, Input, Image, Dropdown, Transition, Popup, Item, Icon, Header } from 'semantic-ui-react'
3-
import { connect } from 'dva'
1+
/* eslint-disable react/jsx-key */
2+
/* eslint-disable react/prop-types */
3+
import { connect } from 'dva';
4+
import React, { Component } from 'react';
5+
import { Feed, Header, Icon } from 'semantic-ui-react';
46

57
@connect(({ artwork }) => ({
6-
artwork
8+
artwork,
79
}))
8-
export default class WikiNews extends Component {
10+
class WikiNews extends Component {
911
constructor(props) {
10-
super()
12+
super();
1113
this.state = {
12-
ready: false
13-
}
14+
ready: false,
15+
};
1416
}
1517

16-
1718
render() {
18-
const h = this.props.artwork.history
19+
const h = this.props.artwork.history;
1920
if (!h.data) {
20-
return null
21+
return null;
2122
}
22-
var date = h.date
23-
var events = h.data.Events
24-
var births = h.data.Births
25-
var deaths = h.data.Deaths
23+
var date = h.date;
24+
var events = h.data.Events;
25+
var births = h.data.Births;
26+
var deaths = h.data.Deaths;
2627
return (
2728
<div style={{ width: 300 }}>
2829
<Header>Today in history</Header>
2930
<Feed>
30-
{
31-
events.map((it) => (
32-
<Feed.Event>
33-
<Feed.Label>
34-
<Icon name="newspaper" />
35-
</Feed.Label>
36-
<Feed.Content>
37-
<Feed.Summary>
38-
{it.text}
39-
</Feed.Summary>
40-
<Feed.Date>
41-
{date + ", " + it.year}
42-
</Feed.Date>
43-
</Feed.Content>
44-
</Feed.Event>
45-
))
46-
}
47-
{
48-
births.map((it) => (
49-
<Feed.Event>
50-
<Feed.Label>
51-
<Icon name="birthday" />
52-
</Feed.Label>
53-
<Feed.Content>
54-
<Feed.Summary>
55-
{it.text + " was born."}
56-
</Feed.Summary>
57-
<Feed.Date>
58-
{date + ", " + it.year}
59-
</Feed.Date>
60-
</Feed.Content>
61-
</Feed.Event>
62-
))
63-
}
31+
{events.map(it => (
32+
<Feed.Event>
33+
<Feed.Label>
34+
<Icon name="newspaper" />
35+
</Feed.Label>
36+
<Feed.Content>
37+
<Feed.Summary>{it.text}</Feed.Summary>
38+
<Feed.Date>{date + ', ' + it.year}</Feed.Date>
39+
</Feed.Content>
40+
</Feed.Event>
41+
))}
42+
{births.map(it => (
43+
<Feed.Event>
44+
<Feed.Label>
45+
<Icon name="birthday" />
46+
</Feed.Label>
47+
<Feed.Content>
48+
<Feed.Summary>{it.text + ' was born.'}</Feed.Summary>
49+
<Feed.Date>{date + ', ' + it.year}</Feed.Date>
50+
</Feed.Content>
51+
</Feed.Event>
52+
))}
6453

65-
{
66-
deaths.map((it) => (
67-
<Feed.Event>
68-
<Feed.Label>
69-
<Icon name="bed" />
70-
</Feed.Label>
71-
<Feed.Content>
72-
<Feed.Summary>
73-
{it.text + " died."}
74-
</Feed.Summary>
75-
<Feed.Date>
76-
{date + ", " + it.year}
77-
</Feed.Date>
78-
</Feed.Content>
79-
</Feed.Event>
80-
))
81-
}
82-
<p>Learn more on <a href="https://en.wikipedia.org/wiki/Wikipedia:On_this_day/Today">Wikipedia.</a></p>
54+
{deaths.map(it => (
55+
<Feed.Event>
56+
<Feed.Label>
57+
<Icon name="bed" />
58+
</Feed.Label>
59+
<Feed.Content>
60+
<Feed.Summary>{it.text + ' died.'}</Feed.Summary>
61+
<Feed.Date>{date + ', ' + it.year}</Feed.Date>
62+
</Feed.Content>
63+
</Feed.Event>
64+
))}
65+
<p>
66+
Learn more on{' '}
67+
<a href="https://en.wikipedia.org/wiki/Wikipedia:On_this_day/Today">
68+
Wikipedia.
69+
</a>
70+
</p>
8371
</Feed>
8472
</div>
85-
)
73+
);
8674
}
87-
}
75+
}
76+
77+
export default Wikinews;

‎src/components/pages/ArtPage.js

+123-120
Original file line numberDiff line numberDiff line change
@@ -1,131 +1,134 @@
1+
/* eslint-disable react/prop-types */
12
import { connect } from 'dva';
2-
import React, { Component } from "react";
3+
import React, { Component } from 'react';
34
import Lightbox from 'react-image-lightbox';
4-
import "react-image-lightbox/style.css";
5-
import { Button, Container, Grid, Header, Icon, Image, Segment } from "semantic-ui-react";
6-
import genColor from '../../utils/genColor'
7-
5+
import 'react-image-lightbox/style.css';
6+
import {
7+
Button,
8+
Container,
9+
Grid,
10+
Header,
11+
Icon,
12+
Image,
13+
Segment,
14+
} from 'semantic-ui-react';
15+
import genColor from '../../utils/genColor';
816

917
export default class ArtPage extends Component {
18+
constructor(props) {
19+
super();
20+
this.state = {};
21+
}
1022

11-
constructor(props) {
12-
super()
13-
this.state = {}
14-
}
15-
16-
render() {
17-
return (
18-
<div className="section">
19-
<div className="home page wrapper">
20-
<div className="content wrapper">
21-
<div className="art wrapper">
22-
<Art />
23-
</div>
24-
</div>
25-
</div>
26-
</div>
27-
)
28-
}
23+
render() {
24+
return (
25+
<div className="section">
26+
<div className="home page wrapper">
27+
<div className="content wrapper">
28+
<div className="art wrapper">
29+
<Art />
30+
</div>
31+
</div>
32+
</div>
33+
</div>
34+
);
35+
}
2936
}
3037

3138
@connect(({ artwork }) => ({
32-
artwork
39+
artwork,
3340
}))
3441
class Art extends Component {
42+
constructor(props) {
43+
super(props);
44+
this.state = { lightboxIsOpen: false };
45+
}
3546

36-
constructor(props) {
37-
super(props)
38-
this.state = { lightboxIsOpen: false }
39-
}
40-
41-
render() {
42-
const a = this.props.artwork.artwork
43-
console.log(a)
44-
if (!a._links) {
45-
return null;
46-
}
47-
const imageHref = a._links.image.href.replace("{image_version}", "large")
48-
const thumbnailHref = a._links.thumbnail.href
49-
const { lightboxIsOpen } = this.state
50-
return (
51-
<Segment vertical style={{ marginTop: 100 }}>
52-
<Container
53-
textAlign='center'
54-
vertical
55-
fluid
56-
>
57-
<Grid columns={2} textAlign='center' verticalAlign='middle' divided >
58-
<Grid.Column width={8}>
59-
<Grid.Row>
60-
{lightboxIsOpen && (
61-
<Lightbox
62-
mainSrc={imageHref}
63-
onCloseRequest={() => this.setState({ lightboxIsOpen: false })}
64-
/>
65-
)}
66-
<div>
67-
<Image
68-
src={imageHref}
69-
size='large'
70-
onClick={() => this.setState({ lightboxIsOpen: true })}
71-
floated='right'
72-
style={{ marginRight: '7vw' }}
73-
/>
74-
<div style={{ clear: 'both' }}>
75-
</div>
76-
</div>
77-
<Header size='tiny' color='grey' textAlign='center'>click the artwork to enlarge</Header>
78-
</Grid.Row>
79-
</Grid.Column>
80-
<Grid.Column width={8} >
81-
<div style={{ marginLeft: '7vw' }}>
82-
<Grid.Row style={{ marginBottom: 20 }}>
83-
<Header
84-
as='h1'
85-
textAlign='left'
86-
>
87-
{this.props.artwork.artworkArtist}
88-
</Header>
89-
</Grid.Row>
90-
<Grid.Row style={{ marginTop: 20, marginBottom: 20 }}>
91-
<Header
92-
as='h1'
93-
color={genColor()}
94-
textAlign='left'
95-
style={{ fontStyle: 'italic' }}
96-
>
97-
{a.title}
98-
</Header>
99-
</Grid.Row>
100-
<Grid.Row style={{ marginTop: 150, marginBottom: 10 }}>
101-
<Header
102-
as='h3'
103-
color='grey'
104-
textAlign='left'
105-
>
106-
{a.medium}, {a.dimensions.cm.text}
107-
</Header>
108-
</Grid.Row>
109-
<Grid.Row style={{ marginTop: 10, marginBottom: 10 }}>
110-
<Header
111-
as='h3'
112-
color='grey'
113-
textAlign='left'
114-
>
115-
{a.collecting_institution}
116-
</Header>
117-
</Grid.Row>
118-
<Grid.Row>
119-
<Button icon labelPosition='left' as='a' color={genColor()} href={a._links.permalink.href} floated='left' target='_blank' style={{ marginTop: 10 }}>
120-
<Icon name='info' />
121-
Learn more on artsy.net
122-
</Button>
123-
</Grid.Row>
124-
</div>
125-
</Grid.Column>
126-
</Grid>
127-
</Container>
128-
</Segment >
129-
)
130-
}
131-
}
47+
render() {
48+
const a = this.props.artwork.artwork;
49+
console.log(a);
50+
if (!a._links) {
51+
return null;
52+
}
53+
const imageHref = a._links.image.href.replace('{image_version}', 'large');
54+
const thumbnailHref = a._links.thumbnail.href;
55+
const { lightboxIsOpen } = this.state;
56+
return (
57+
<Segment vertical style={{ marginTop: 100 }}>
58+
<Container textAlign="center" vertical fluid>
59+
<Grid columns={2} textAlign="center" verticalAlign="middle" divided>
60+
<Grid.Column width={8}>
61+
<Grid.Row>
62+
{lightboxIsOpen && (
63+
<Lightbox
64+
mainSrc={imageHref}
65+
onCloseRequest={() =>
66+
this.setState({ lightboxIsOpen: false })
67+
}
68+
/>
69+
)}
70+
<div>
71+
<Image
72+
src={imageHref}
73+
size="large"
74+
onClick={() => this.setState({ lightboxIsOpen: true })}
75+
floated="right"
76+
style={{ marginRight: '7vw' }}
77+
/>
78+
<div style={{ clear: 'both' }}></div>
79+
</div>
80+
<Header size="tiny" color="grey" textAlign="center">
81+
click the artwork to enlarge
82+
</Header>
83+
</Grid.Row>
84+
</Grid.Column>
85+
<Grid.Column width={8}>
86+
<div style={{ marginLeft: '7vw' }}>
87+
<Grid.Row style={{ marginBottom: 20 }}>
88+
<Header as="h1" textAlign="left">
89+
{this.props.artwork.artworkArtist}
90+
</Header>
91+
</Grid.Row>
92+
<Grid.Row style={{ marginTop: 20, marginBottom: 20 }}>
93+
<Header
94+
as="h1"
95+
color={genColor()}
96+
textAlign="left"
97+
style={{ fontStyle: 'italic' }}
98+
>
99+
{a.title}
100+
</Header>
101+
</Grid.Row>
102+
<Grid.Row style={{ marginTop: 150, marginBottom: 10 }}>
103+
<Header as="h3" color="grey" textAlign="left">
104+
{a.medium}, {a.dimensions.cm.text}
105+
</Header>
106+
</Grid.Row>
107+
<Grid.Row style={{ marginTop: 10, marginBottom: 10 }}>
108+
<Header as="h3" color="grey" textAlign="left">
109+
{a.collecting_institution}
110+
</Header>
111+
</Grid.Row>
112+
<Grid.Row>
113+
<Button
114+
icon
115+
labelPosition="left"
116+
as="a"
117+
color={genColor()}
118+
href={a._links.permalink.href}
119+
floated="left"
120+
target="_blank"
121+
style={{ marginTop: 10 }}
122+
>
123+
<Icon name="info" />
124+
Learn more on artsy.net
125+
</Button>
126+
</Grid.Row>
127+
</div>
128+
</Grid.Column>
129+
</Grid>
130+
</Container>
131+
</Segment>
132+
);
133+
}
134+
}

‎src/components/pages/HomePage.js

+138-102
Original file line numberDiff line numberDiff line change
@@ -1,139 +1,151 @@
1+
/* eslint-disable react/prop-types */
12
import { connect } from 'dva';
23
import React, { PureComponent } from 'react';
34
import ReactWordcloud from 'react-wordcloud';
4-
import { Button, Divider, Form, Grid, Header, Icon, Image, Input, Menu, Popup, Radio, Transition } from 'semantic-ui-react';
5+
import {
6+
Button,
7+
Divider,
8+
Form,
9+
Grid,
10+
Header,
11+
Icon,
12+
Image,
13+
Input,
14+
Menu,
15+
Popup,
16+
Radio,
17+
Transition,
18+
} from 'semantic-ui-react';
519
import genColor from '../../utils/genColor';
620
import Calendar from '../Calendar';
721
import './HomePage.css';
822

923
@connect(({ artwork }) => ({
10-
artwork
24+
artwork,
1125
}))
12-
export default class HomePage extends PureComponent {
13-
14-
domRef
26+
class HomePage extends PureComponent {
27+
domRef;
1528
constructor(props) {
16-
super(props)
17-
this.fpMoveTo = props.fpMoveTo
18-
this.domRef = React.createRef()
29+
super(props);
30+
this.fpMoveTo = props.fpMoveTo;
31+
this.domRef = React.createRef();
1932
this.engineCollection = [
2033
{
2134
key: 'google',
2235
name: 'Google',
2336
baseString: 'https://www.google.com/search?q=',
24-
iconName: 'google'
37+
iconName: 'google',
2538
},
2639
{
2740
key: 'bing',
2841
name: 'Bing',
2942
baseString: 'https://www.bing.com/search?q=',
30-
iconName: 'microsoft'
43+
iconName: 'microsoft',
3144
},
3245
{
3346
key: 'duckduckgo',
3447
name: 'DuckDuckGo',
3548
baseString: 'https://duckduckgo.com/?q=',
36-
iconName: 'privacy'
49+
iconName: 'privacy',
3750
},
3851
{
3952
key: 'baidu',
4053
name: 'Baidu',
4154
baseString: 'https://www.baidu.com/s?wd=',
42-
iconName: 'dont'
43-
}
44-
]
55+
iconName: 'dont',
56+
},
57+
];
4558
this.state = {
4659
engine: this.engineCollection[0],
4760
query: null,
4861
isLogoVisible: true,
4962
searchInNewWindow: false,
5063
isArrowVisible: false,
5164
artwork: {},
52-
53-
}
54-
this.handleMenuItemClick = this.handleMenuItemClick.bind(this)
55-
this.handleFormSubmit = this.handleFormSubmit.bind(this)
56-
this.handleInputChange = this.handleInputChange.bind(this)
57-
this.handleRadioClick = this.handleRadioClick.bind(this)
58-
65+
};
66+
this.handleMenuItemClick = this.handleMenuItemClick.bind(this);
67+
this.handleFormSubmit = this.handleFormSubmit.bind(this);
68+
this.handleInputChange = this.handleInputChange.bind(this);
69+
this.handleRadioClick = this.handleRadioClick.bind(this);
5970
}
6071

6172
componentDidMount() {
62-
this.props.dispatch({ type: 'artwork/getData' })
73+
this.props.dispatch({ type: 'artwork/getData' });
6374
}
6475

6576
move = () => {
6677
// console.log("123")
6778
if (!this.state.isArrowVisible) {
68-
this.setState({ isArrowVisible: true }, this.arrowDisappear)
79+
this.setState({ isArrowVisible: true }, this.arrowDisappear);
6980
}
70-
}
81+
};
7182

72-
timer
83+
timer;
7384
arrowDisappear = () => {
7485
if (this.timer) {
75-
clearTimeout(this.timer)
86+
clearTimeout(this.timer);
7687
}
7788
this.timer = setTimeout(() => {
78-
this.setState({ isArrowVisible: false })
79-
this.timer = null
80-
}, 2000)
81-
}
89+
this.setState({ isArrowVisible: false });
90+
this.timer = null;
91+
}, 2000);
92+
};
8293

8394
handleMenuItemClick(e, d) {
84-
this.setState({ isLogoVisible: false })
85-
const engineName = d.content.toLowerCase()
86-
const engineObject = this.engineCollection.find(
87-
(i) => i.key == engineName
88-
)
89-
console.log(engineObject)
95+
this.setState({ isLogoVisible: false });
96+
const engineName = d.content.toLowerCase();
97+
const engineObject = this.engineCollection.find(i => i.key == engineName);
98+
console.log(engineObject);
9099
this.setState({
91-
engine: engineObject
92-
})
100+
engine: engineObject,
101+
});
93102
setTimeout(() => {
94103
this.setState({
95-
isLogoVisible: true
96-
})
97-
console.log(this.state.isLogoVisible)
98-
console.log(engineObject)
99-
}, 100)
104+
isLogoVisible: true,
105+
});
106+
console.log(this.state.isLogoVisible);
107+
console.log(engineObject);
108+
}, 100);
100109
}
101110

111+
handleColorShuffle = () => {
112+
localStorage['colorOffset'] = localStorage['colorOffset'] + 1;
113+
};
114+
102115
handleFormSubmit(e) {
103-
const s = this.state
104-
const address = s.engine.baseString + s.query
116+
const s = this.state;
117+
const address = s.engine.baseString + s.query;
105118
if (s.query == null) {
106119
//todo: made this look nicer (and more politer lol)
107-
alert('FILL THE DAMNED SEARCH BOX FIRST!')
108-
return 0
120+
alert('FILL THE DAMNED SEARCH BOX FIRST!');
121+
return 0;
109122
}
110123
if (s.searchInNewWindow) {
111-
window.open(address, "_blank")
112-
}
113-
else {
114-
e.currentTarget.reset()
115-
window.open(address, "_self")
124+
window.open(address, '_blank');
125+
} else {
126+
e.currentTarget.reset();
127+
window.open(address, '_self');
116128
}
117129
}
118130

119131
handleInputChange(e) {
120-
const queryString = e.target.value
132+
const queryString = e.target.value;
121133
this.setState({
122-
query: queryString
123-
})
134+
query: queryString,
135+
});
124136
}
125137

126138
handleRadioClick() {
127-
this.setState((prevState) => ({
128-
searchInNewWindow: !prevState.searchInNewWindow
129-
}))
130-
console.log("state:" + this.state.searchInNewWindow)
139+
this.setState(prevState => ({
140+
searchInNewWindow: !prevState.searchInNewWindow,
141+
}));
142+
console.log('state:' + this.state.searchInNewWindow);
131143
}
132144

133145
render() {
134-
const s = this.state
135-
console.log(this.props.artwork)
136-
console.log(s.engine.key)
146+
const s = this.state;
147+
console.log(this.props.artwork);
148+
console.log(s.engine.key);
137149
return (
138150
<div onMouseMove={this.move} className="section">
139151
<div className="home page wrapper">
@@ -145,20 +157,26 @@ export default class HomePage extends PureComponent {
145157
<Grid centered fluid>
146158
<Grid.Row>
147159
<Grid.Column textAlign="center">
148-
<Transition visible={s.isLogoVisible} duration={200} animation="pulse">
160+
<Transition
161+
visible={s.isLogoVisible}
162+
duration={200}
163+
animation="pulse"
164+
>
149165
<Image>
150-
<Icon name={s.engine.iconName} size="massive" color={genColor()} />
166+
<Icon
167+
name={s.engine.iconName}
168+
size="massive"
169+
color={genColor()}
170+
/>
151171
</Image>
152172
</Transition>
153173
</Grid.Column>
154174
</Grid.Row>
155175
<Grid.Row>
156176
<Grid.Column width={8}>
157-
<Form
158-
onSubmit={this.handleFormSubmit}
159-
>
177+
<Form onSubmit={this.handleFormSubmit}>
160178
<Input
161-
placeholder='All engines, one Pano.'
179+
placeholder="All engines, one Pano."
162180
type="input"
163181
action="Search"
164182
fluid
@@ -180,43 +198,55 @@ export default class HomePage extends PureComponent {
180198
radioClick={this.handleRadioClick}
181199
engine={s.engine.key}
182200
newWindow={s.searchInNewWindow}
201+
shuffleColor={this.handleColorshuffle}
183202
/>
184203
</div>
185204
</div>
186-
<Transition
187-
visible={s.isArrowVisible}
188-
duration={100}
189-
>
190-
<div style={{ position: 'fixed', bottom: 25, width: "50%", left: "25%", textAlign: "center" }}>
191-
<Button circular icon='angle double down' onClick={
192-
() => {
193-
this.setState({ isArrowVisible: false }, () => this.fpMoveTo(2))
205+
<Transition visible={s.isArrowVisible} duration={100}>
206+
<div
207+
style={{
208+
position: 'fixed',
209+
bottom: 25,
210+
width: '50%',
211+
left: '25%',
212+
textAlign: 'center',
213+
}}
214+
>
215+
<Button
216+
circular
217+
icon="angle double down"
218+
onClick={() => {
219+
this.setState({ isArrowVisible: false }, () =>
220+
this.fpMoveTo(2),
221+
);
194222
}}
195223
/>
196224
</div>
197225
</Transition>
198226
</div>
199-
)
227+
);
200228
}
201229
}
202230

203231
function Footer(props) {
204-
const p = props
232+
const p = props;
205233
return (
206234
<>
207-
<Popup className="footer-icon"
208-
trigger={<Button circular color='green' icon='wechat' />}
235+
<Popup
236+
className="footer-icon"
237+
trigger={<Button circular color="green" icon="wechat" />}
209238
>
210-
<Image src='https://s3.ax1x.com/2020/11/22/D3WBZQ.jpg' />
239+
<Image src="https://s3.ax1x.com/2020/11/22/D3WBZQ.jpg" />
211240
</Popup>
212-
<Popup className="footer-icon"
213-
trigger={<Button circular color='twitter' icon='twitter' />}
241+
<Popup
242+
className="footer-icon"
243+
trigger={<Button circular color="twitter" icon="twitter" />}
214244
>
215245
<Header>Pending.</Header>
216246
</Popup>
217247
<span className="custom-divider">|</span>
218248
<Popup
219-
trigger={<Button circular icon='setting' className="footer-icon" />}
249+
trigger={<Button circular icon="setting" className="footer-icon" />}
220250
position="top left"
221251
flowing
222252
hoverable
@@ -246,34 +276,40 @@ function Footer(props) {
246276
<Divider />
247277
<Menu.Item fitted>
248278
<Radio
249-
label='Search in new tab'
279+
label="Search in new tab"
250280
slider
251281
checked={p.newWindow}
252282
onClick={p.radioClick}
253283
/>
254284
</Menu.Item>
285+
<Menu.Item fitted>
286+
<Button label="shuffle accent color" onClick={p.shuffleColor} />
287+
</Menu.Item>
255288
</Menu>
256289
</Popup>
257290
</>
258-
)
291+
);
259292
}
260293

261294
class Wordcloud extends PureComponent {
262295
render() {
263-
return (<ReactWordcloud
264-
words={this.props.data}
265-
size={[100, 800]}
266-
options={{
267-
fontSizes: [20, 30],
268-
rotations: 90,
269-
rotationAngles: [-90, 0]
270-
}}
271-
callbacks={{
272-
onWordMouseOver: null,
273-
getWordTooltip: word => '',
274-
getWordColor: word => '#999',
275-
}
276-
}
277-
/>)
296+
return (
297+
<ReactWordcloud
298+
words={this.props.data}
299+
size={[100, 800]}
300+
options={{
301+
fontSizes: [20, 30],
302+
rotations: 90,
303+
rotationAngles: [-90, 0],
304+
}}
305+
callbacks={{
306+
onWordMouseOver: null,
307+
getWordTooltip: word => '',
308+
getWordColor: word => '#999',
309+
}}
310+
/>
311+
);
278312
}
279-
}
313+
}
314+
315+
export default HomePage;

‎src/components/pages/QuotePage.js

+46-36
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,55 @@
1-
import React, { Component } from "react";
1+
import React, { Component } from 'react';
22
import { Button, Icon, Header } from 'semantic-ui-react';
33
import Quote from '../Quote';
44
import './QuotePage.css';
55

66
export default class ArtPage extends Component {
7+
constructor(props) {
8+
super(props);
9+
this.state = {};
10+
}
711

8-
constructor(props) {
9-
super(props)
10-
this.state = {}
11-
}
12-
13-
render() {
14-
return (
15-
<div className="section">
16-
<div className="home page wrapper">
17-
<div className="content wrapper">
18-
<div className="quote wrapper">
19-
<Quote />
20-
</div>
21-
</div>
22-
<div className="footer wrapper">
23-
<Footer />
24-
</div>
25-
</div>
26-
</div>
27-
)
28-
}
12+
render() {
13+
return (
14+
<div className="section">
15+
<div className="home page wrapper">
16+
<div className="content wrapper">
17+
<div className="quote wrapper">
18+
<Quote />
19+
</div>
20+
</div>
21+
<div className="footer wrapper">
22+
<Footer />
23+
</div>
24+
</div>
25+
</div>
26+
);
27+
}
2928
}
3029

3130
function Footer(props) {
32-
const p = props
33-
return (
34-
<div style={{ textAlign: 'center' }}>
35-
<Header as='span' size='tiny' color='grey' style={{ verticalAlign: 'middle', marginRight: 10 }}>
36-
Pano is an open-source startpage by BedrockDigger.
37-
A start panel for web browsing, a panorama of inspiration.
38-
Powered by React × Feathers.
39-
</Header>
40-
<Button as='a' icon color='black' href='https://github.com/BedrockDigger/pano-react-app' target='_blank' circular>
41-
<Icon name='github' />
42-
</Button>
43-
</div>
44-
)
45-
}
31+
const p = props;
32+
return (
33+
<div style={{ textAlign: 'center' }}>
34+
<Header
35+
as="span"
36+
size="tiny"
37+
color="grey"
38+
style={{ verticalAlign: 'middle', marginRight: 10 }}
39+
>
40+
Pano is an open-source startpage by BedrockDigger. A start panel for web
41+
browsing, a panorama of inspiration. Powered by React × Feathers.
42+
</Header>
43+
<Button
44+
as="a"
45+
icon
46+
color="black"
47+
href="https://github.com/BedrockDigger/pano-react-app"
48+
target="_blank"
49+
circular
50+
>
51+
<Icon name="github" />
52+
</Button>
53+
</div>
54+
);
55+
}

‎src/models/artwork.js

+17-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
1-
import fetchData from '../utils/fetchData'
1+
import fetchData from '../utils/fetchData';
22

33
export default {
44
namespace: 'artwork',
55
state: { history: {}, artwork: {}, wordcloud: [], quote: '' },
66
effects: {
77
*getData({ payload }, { call, put }) {
88
const data = yield call(fetchData);
9-
yield put({ type: 'saveData', payload: { history: data[1], artwork: data[0], wordcloud: data[2], artworkArtist: data[3], quoteSpeaker: data[4], quoteContent: data[5] } })
10-
}
9+
yield put({
10+
type: 'saveData',
11+
payload: {
12+
history: data[1],
13+
artwork: data[0],
14+
wordcloud: data[2],
15+
artworkArtist: data[3],
16+
quoteSpeaker: data[4],
17+
quoteContent: data[5],
18+
},
19+
});
20+
},
1121
},
1222
reducers: {
1323
saveData(state, { payload }) {
14-
return { ...state, ...payload }
15-
}
16-
}
17-
}
24+
return { ...state, ...payload };
25+
},
26+
},
27+
};

‎src/pages/index.js

+12-14
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,41 @@
1+
/* eslint-disable react/no-deprecated */
12
import ReactFullpage from '@fullpage/react-fullpage';
23
import React, { Component } from 'react';
34
import 'semantic-ui-css/semantic.min.css';
45
import ArtPage from '../components/pages/ArtPage';
56
import HomePage from '../components/pages/HomePage';
67
import QuotePage from '../components/pages/QuotePage';
78
import TopHeader from '../components/TopHeader';
9+
import Welcome from '../components/WelcomeModal';
810
import './index.less';
9-
import Welcome from '../components/WelcomeModal'
10-
1111

1212
class App extends Component {
13-
1413
constructor(props) {
15-
super()
14+
super();
1615
}
1716

1817
componentWillMount() {
19-
let visited = localStorage['alreadyVisited']
18+
let visited = localStorage['alreadyVisited'];
2019
if (visited) {
21-
this.setState({ newUser: false })
22-
}
23-
else {
24-
localStorage['alreadyVisited'] = true
25-
this.setState({ newUser: true })
20+
this.setState({ newUser: false });
21+
} else {
22+
localStorage['alreadyVisited'] = true;
23+
this.setState({ newUser: true });
2624
}
2725
}
2826
render() {
29-
const s = this.state
27+
const s = this.state;
3028
return (
3129
<>
3230
{s.newUser && <Welcome />}
3331
<ReactFullpage
3432
easing="easeOutExpo"
3533
scrollingSpeed={500}
3634
scrollBar={true}
37-
render={(fpSettings) => {
35+
render={fpSettings => {
3836
return (
3937
<ReactFullpage.Wrapper>
40-
<HomePage fpMoveTo={(n) => fpSettings.fullpageApi.moveTo(n)} />
38+
<HomePage fpMoveTo={n => fpSettings.fullpageApi.moveTo(n)} />
4139
<ArtPage />
4240
<QuotePage />
4341
</ReactFullpage.Wrapper>
@@ -46,7 +44,7 @@ class App extends Component {
4644
/>
4745
<TopHeader />
4846
</>
49-
)
47+
);
5048
}
5149
}
5250

‎src/utils/fetchData.js

+21-19
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
// import axios from 'axios'
2-
import { fetch } from 'dva'
2+
import { fetch } from 'dva';
33

44
export default async () => {
55
return new Promise((resolve, reject) => {
6-
fetch('/receptionist', { method: 'GET' }).then(
7-
(res) => {
8-
res.json().then(
9-
(ret) => {
10-
const artwork = ret.data[0].data
11-
const history = ret.data[1].data
12-
const wordcloud = ret.data[2].data
13-
const quoteSpeaker = ret.data[5]
14-
const quoteContent = ret.data[4]
15-
const artworkArtist = ret.data[3]
16-
resolve([artwork, history, wordcloud, artworkArtist, quoteSpeaker, quoteContent])
17-
}
18-
)
19-
}
20-
)
21-
}
22-
)
23-
}
6+
fetch('/receptionist', { method: 'GET' }).then(res => {
7+
res.json().then(ret => {
8+
const artwork = ret.data[0].data;
9+
const history = ret.data[1].data;
10+
const wordcloud = ret.data[2].data;
11+
const quoteSpeaker = ret.data[5];
12+
const quoteContent = ret.data[4];
13+
const artworkArtist = ret.data[3];
14+
resolve([
15+
artwork,
16+
history,
17+
wordcloud,
18+
artworkArtist,
19+
quoteSpeaker,
20+
quoteContent,
21+
]);
22+
});
23+
});
24+
});
25+
};

‎src/utils/genColor.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
export default function genColor() {
2-
const colors = ["red", "orange", "yellow", "green", "teal", "blue", "violet"]
3-
const index = new Date().getDay()
4-
return colors[index]
5-
}
2+
let offset = localStorage['colorOffset'];
3+
if (!offset) {
4+
localStorage['colorOffset'] = 0;
5+
}
6+
const colors = ['red', 'orange', 'yellow', 'green', 'teal', 'blue', 'violet'];
7+
const index = (new Date().getDay() + offset) % 7;
8+
return colors[index];
9+
}

0 commit comments

Comments
 (0)
Please sign in to comment.