├── .babelrc
├── .github
└── workflows
│ └── semgrep.yml
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── package.json
├── screenshots
├── tv-roll-mid.jpg
└── tv-roll-top.jpg
├── src
├── inferno
│ ├── components
│ │ └── welcome-component.js
│ ├── index-template.html
│ ├── index.js
│ └── styles
│ │ └── stylesheet.css
├── mincss
│ ├── img
│ │ ├── asia.png
│ │ ├── beach.png
│ │ ├── bees.png
│ │ ├── coffee.png
│ │ ├── documentaries.png
│ │ ├── forest.png
│ │ ├── logo.svg
│ │ ├── seats.jpg
│ │ ├── shoes.png
│ │ └── spiderman.jpg
│ ├── index-template.html
│ ├── index.js
│ └── styles
│ │ └── styles.less
├── photo
│ ├── components
│ │ ├── blob-component.js
│ │ ├── card-component.js
│ │ ├── footer-component.js
│ │ ├── header-component.js
│ │ ├── main-component.js
│ │ └── top-header-component.js
│ ├── favicon.ico
│ ├── img
│ │ └── logo.svg
│ ├── index-template.html
│ ├── index.js
│ ├── styles
│ │ └── styles.less
│ └── tvmaze.js
└── purecss
│ ├── index-template.html
│ ├── index.js
│ └── styles
│ └── styles.css
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "es2015" ],
3 | "plugins": [["inferno", {"imports": true}]]
4 | }
5 |
--------------------------------------------------------------------------------
/.github/workflows/semgrep.yml:
--------------------------------------------------------------------------------
1 | on:
2 | pull_request: {}
3 | push:
4 | branches:
5 | - main
6 | - master
7 | paths:
8 | - .github/workflows/semgrep.yml
9 | schedule:
10 | - cron: '0 0 * * 0'
11 | name: Semgrep
12 | jobs:
13 | semgrep:
14 | name: Scan
15 | runs-on: ubuntu-20.04
16 | env:
17 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
18 | container:
19 | image: returntocorp/semgrep
20 | steps:
21 | - uses: actions/checkout@v3
22 | - run: semgrep ci
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | static
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # Travis build config
2 | sudo: false
3 | language: node_js
4 | node_js:
5 | - "5.10.1"
6 |
7 | cache:
8 | directories:
9 | - node_modules
10 |
11 | install:
12 | - npm install
13 |
14 | script:
15 | - npm run test
16 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hirako2000@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hirako
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://app.codacy.com/app/hirako2000/polypack?utm_source=github.com&utm_medium=referral&utm_content=hirako2000/polypack&utm_campaign=Badge_Grade_Dashboard)
2 | [](https://travis-ci.org/hirako2000/polypack)
3 | [](https://david-dm.org/hirako2000/polypack)
4 | [](https://david-dm.org/hirako2000/polypack#info=devDependencies)
5 | [](https://github.com/hirako2000/polypack/blob/master/LICENSE)
6 |
7 | # polypack
8 |
9 | Polypack is a boilerplate configuration to build the most lightweight front end assets for webapp or static pages.
10 |
11 | The motivation behind this project started from observation that most if not all boilerplates are either bloated with heavyweight libs, or incomplete in order to develop and ship production applications.
12 |
13 | ### Features
14 |
15 | - Ready to use build and bundling system with [webpack](https://webpack.github.io/)
16 | - Most lightweight libraries for [performance](https://medium.com/reloading/javascript-start-up-performance-69200f43b201)
17 | - Web application, react-like skeleton
18 | - State store
19 | - Static web page setup
20 | - Support for either or both [{less}](http://lesscss.org/)/[Sass](http://sass-lang.com/)
21 | - Support for various web fonts formats
22 | - [Hot Module Replacement](https://webpack.js.org/concepts/hot-module-replacement/) for rapid development
23 | - ES6/7
24 | - Linting
25 | - Production build with minified, concat and gzipped content
26 |
27 | ### Roadmap
28 |
29 | - [x] Base bundler with webpack 3 & Babel
30 | - [x] Multi SPA bundler config
31 | - [x] Hot Module Reload
32 | - [x] Production build
33 | - [x] Cross environment variables
34 | - [x] Gzip
35 | - [x] Less support
36 | - [x] Sass support
37 | - [x] Fonts support
38 | - [x] Inferno JS skeleton
39 | - [x] Redux skeleton
40 | - [x] PureCSS skeleton
41 | - [x] mincss skeleton
42 | - [x] Inferno sample webapp
43 | - [x] Linter
44 | - [ ] Jest
45 |
46 | ### TV program roll webapp example with Inferno/redux & mincss
47 |
48 | HBO look & feel with [Mincss](http://mincss.com/)
49 |
50 | [Live Demo](http://polypack-tv.surge.sh/)
51 |
52 | 
53 | 
54 |
55 | #### Size
56 |
57 | ```
58 | Asset Size Chunks Chunk Names
59 | bcff9e9b7b53122acb52df67cd5f4d4f.svg 1.99 kB [emitted]
60 | photo.js 14.6 kB 0 [emitted] photo
61 | photo.vendor.js 114 kB 4 [emitted] photo.vendor
62 | photo.css 3.97 kB 0 [emitted] photo
63 | photo.vendor.css 1.95 kB 4 [emitted] photo.vendor
64 | photo.html 398 bytes [emitted]
65 | ```
66 | #### Size (gzipped)
67 | ```
68 | bcff9e9b7b53122acb52df67cd5f4d4f.svg.gz 901 bytes [emitted]
69 | photo.js.gz 2.88 kB [emitted]
70 | photo.vendor.js.gz 27.9 kB [emitted]
71 | photo.css.gz 1.32 kB [emitted]
72 | photo.vendor.css.gz 850 bytes [emitted]
73 | photo.html 398 bytes [emitted]
74 | ```
75 | ### Potato shop
76 | Landing page with Inferno & [Basscss](http://basscss.com/)
77 |
78 | [Live Demo](https://eager-potatoes.surge.sh/) | [Source](https://github.com/hirako2000/polypack-potatoes)
79 |
80 | 
81 |
82 | #### Size
83 |
84 | ```
85 | Asset Size Chunks Chunk Names
86 | potatoes.css.map 89 bytes 0 [emitted] potatoes
87 | potatoes.js 21.9 kB 0 [emitted] potatoes
88 | potatoes.vendor.js 51.4 kB 1 [emitted] potatoes.vendor
89 | potatoes.css 4.65 kB 0 [emitted] potatoes
90 | potatoes.vendor.css 9.89 kB 1 [emitted] potatoes.vendor
91 | potatoes.vendor.css.map 96 bytes 1 [emitted] potatoes.vendor
92 | index.html 418 bytes [emitted]
93 | ```
94 | #### Size (gzipped)
95 | ```
96 | Asset Size Chunks Chunk Names
97 | potatoes.js.gz 3.09 kB [emitted]
98 | potatoes.css.gz 1.98 kB [emitted]
99 | potatoes.vendor.css.gz 2.31 kB [emitted]
100 | potatoes.vendor.js.gz 15.4 kB [emitted]
101 | index.html 418 bytes [emitted]
102 | ```
103 |
104 | ### Folder structure
105 | ```
106 | .
107 | ├── src # Applications source code
108 | │ ├── inferno # Inferno app
109 | │ │ ├── components # Components
110 | │ │ ├── styles # Styles
111 | │ | ├── index-template.html # HTML template
112 | │ | └── index.js # Entry point
113 | │ ├── mincss # Mincss landing page
114 | │ │ ├── img # images
115 | │ │ ├── styles # Styles
116 | │ | ├── index-template.html # HTML template
117 | │ | └── index.js # Entry point
118 | │ ├── photo # Inferno app for TV roll example
119 | │ │ ├── components # Components
120 | │ │ ├── img # Images
121 | │ │ ├── styles # Styles
122 | │ | ├── index-template.html # HTML template
123 | │ | └── index.js # Entry point
124 | │ └── purecss # Purecss landing page
125 | │ ├── img # images
126 | │ ├── styles # Styles
127 | │ ├── index-template.html # HTML template
128 | │ └── index.js # Entry point
129 | ├── static # Output of prod assets
130 | └── webpack.config.js # Webpack config for both dev and prod builds
131 | ```
132 | ### HOWTO
133 | Simply fork, or download the zip content of this repo.
134 | #### Prerequisite
135 | - Node.js
136 |
137 | #### Run
138 | ```bash
139 | npm install # installs deps
140 | ```
141 |
142 | ```bash
143 | npm start # starts the app in dev mode
144 | ```
145 | ```bash
146 | npm run build # builds app for production
147 | ```
148 | #### Browse
149 | There are multiple web apps built by default
150 | - [http://localhost:3000/mincss.html](http://localhost:3000/mincss.html) - mincss starter
151 | - [http://localhost:3000/purecss.html](http://localhost:3000/purecss.html) - purecss starter
152 | - [http://localhost:3000/inferno.html](http://localhost:3000/inferno.html) - inferno/redux starter
153 | - [http://localhost:3000/photo.html](http://localhost:3000/photo.html) - the tv roll exampe (inferno/redux fetching TVmaze schedules)
154 |
155 |
156 | ### Contributing
157 | PR are welcome
158 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "polypack",
3 | "version": "1.0.1",
4 | "description": "Webpack skeleton",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack-dev-server",
8 | "prod": "cross-env NODE_ENV=production webpack-dev-server --env.prod=true",
9 | "build": "cross-env NODE_ENV=production webpack --env.prod=true",
10 | "test": "xo ./src/**/*.js"
11 | },
12 | "keywords": [
13 | "webpack"
14 | ],
15 | "author": "hirako2000",
16 | "repository": "https://github.com/hirako2000/polypack",
17 | "license": "MIT",
18 | "devDependencies": {
19 | "babel-core": "^6.26.3",
20 | "babel-loader": "^7.1.5",
21 | "babel-plugin-inferno": "^3.1.0",
22 | "babel-preset-es2015": "^6.22.0",
23 | "compression-webpack-plugin": "^0.4.0",
24 | "cross-env": "^5.2.0",
25 | "css-loader": "^0.28.4",
26 | "eslint-config-xo": "^0.18.2",
27 | "eslint-config-xo-inferno": "^0.11.1",
28 | "eslint-plugin-inferno": "^6.10.4",
29 | "extract-text-webpack-plugin": "^2.1.2",
30 | "file-loader": "^0.11.2",
31 | "html-loader": "^0.4.4",
32 | "html-webpack-plugin": "^2.29.0",
33 | "less": "^2.7.2",
34 | "less-loader": "^4.1.0",
35 | "style-loader": "^0.18.2",
36 | "url-loader": "^0.5.9",
37 | "webpack": "^3.0.0",
38 | "webpack-dev-server": "^2.5.0",
39 | "xo": "^0.18.2"
40 | },
41 | "dependencies": {
42 | "basscss": "^8.0.4",
43 | "fecha": "^2.3.3",
44 | "furtive": "^2.4.0",
45 | "inferno": "^3.3.1",
46 | "inferno-component": "^3.3.1",
47 | "inferno-redux": "^3.3.1",
48 | "inferno-router": "^3.3.1",
49 | "inferno-shared": "^3.1.1",
50 | "lodash": "^4.17.10",
51 | "mincss-modules": "^2.0.0",
52 | "netflixroulette-js": "0.0.1",
53 | "purecss": "^1.0.0",
54 | "redux": "^3.6.0"
55 | },
56 | "xo": {
57 | "extends": [
58 | "xo/esnext",
59 | "xo-inferno/space"
60 | ],
61 | "env": "browser",
62 | "semicolon": false,
63 | "space": 2,
64 | "unicorn/filename-case": 0,
65 | "import/no-extraneous-dependencies": 0
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/screenshots/tv-roll-mid.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/screenshots/tv-roll-mid.jpg
--------------------------------------------------------------------------------
/screenshots/tv-roll-top.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/screenshots/tv-roll-top.jpg
--------------------------------------------------------------------------------
/src/inferno/components/welcome-component.js:
--------------------------------------------------------------------------------
1 | import Component from 'inferno-component'
2 |
3 | export default class WelcomeComponent extends Component {
4 | constructor(props) {
5 | super(props)
6 | this.state = {
7 | name: 'Inferno'
8 | }
9 | }
10 | render() {
11 | return (
12 |
13 |
{this.props.message} - {this.state.name}
14 |
15 | )
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/inferno/index-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/inferno/index.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import * as furtive from 'furtive/css/furtive.css'
3 | import * as styles from './styles/stylesheet.css'
4 | import WelcomeComponent from './components/welcome-component'
5 |
6 | const message = 'Furtive'
7 | Inferno.render(
8 | ,
12 | document.getElementById('app')
13 | )
14 |
15 | export {furtive, styles}
16 |
--------------------------------------------------------------------------------
/src/inferno/styles/stylesheet.css:
--------------------------------------------------------------------------------
1 | body{
2 | margin: 2%;
3 | }
4 |
5 | .header {
6 | max-height: 60px;
7 | margin: 0;
8 | padding: 0;
9 | }
10 |
11 | .logo {
12 | height: 100px;
13 | }
14 |
--------------------------------------------------------------------------------
/src/mincss/img/asia.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/asia.png
--------------------------------------------------------------------------------
/src/mincss/img/beach.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/beach.png
--------------------------------------------------------------------------------
/src/mincss/img/bees.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/bees.png
--------------------------------------------------------------------------------
/src/mincss/img/coffee.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/coffee.png
--------------------------------------------------------------------------------
/src/mincss/img/documentaries.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/documentaries.png
--------------------------------------------------------------------------------
/src/mincss/img/forest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/forest.png
--------------------------------------------------------------------------------
/src/mincss/img/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Shape
4 | Some Logo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/mincss/img/seats.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/seats.jpg
--------------------------------------------------------------------------------
/src/mincss/img/shoes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/shoes.png
--------------------------------------------------------------------------------
/src/mincss/img/spiderman.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/mincss/img/spiderman.jpg
--------------------------------------------------------------------------------
/src/mincss/index-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 | SERIES
22 | SPORT
23 | DOCUMENTARIES
24 | COMEDY
25 | MOVIES
26 | KIDS
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Spider Man | Premiere sunday at 10:30 PM
39 |
40 |
41 | He is coming back
42 |
43 |
44 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
45 |
46 |
47 | Find out more
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Spider Man | Premiere sunday at 10:30 PM
61 |
62 |
63 | He is coming back
64 |
65 |
66 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
67 |
68 |
69 | Find out more
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | Spider Man | Premiere sunday at 10:30 PM
78 |
79 |
80 | He is coming back
81 |
82 |
83 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
84 |
85 |
86 | Find out more
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | Spider Man | Premiere sunday at 10:30 PM
99 |
100 |
101 | He is coming back
102 |
103 |
104 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
105 |
106 |
107 | Find out more
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | Spider Man | Premiere sunday at 10:30 PM
116 |
117 |
118 | He is coming back
119 |
120 |
121 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
122 |
123 |
124 | Find out more
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 | Spider Man | Premiere sunday at 10:30 PM
133 |
134 |
135 | He is coming back
136 |
137 |
138 | Peter Parker (Tobey Maguire) and M.J. (Kirsten Dunst) seem to finally be on the right track in their complicated relationship, but trouble looms for the superhero and his lover
139 |
140 |
141 | Find out more
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/src/mincss/index.js:
--------------------------------------------------------------------------------
1 | import * as buttons from 'mincss-modules/less/buttons.less'
2 | import * as grid from 'mincss-modules/less/grid.less'
3 | import * as icons from 'mincss-modules/less/icons.less'
4 | import * as navbar from 'mincss-modules/less/navbar.less'
5 | import * as tables from 'mincss-modules/less/tables.less'
6 | import * as forms from 'mincss-modules/less/forms.less'
7 | import * as styles from './styles/styles.less'
8 | import * as logo from './img/logo.svg'
9 |
10 | export {buttons, grid, icons, navbar, tables, forms, styles, logo}
11 |
--------------------------------------------------------------------------------
/src/mincss/styles/styles.less:
--------------------------------------------------------------------------------
1 | @whiteTrans72: rgba(255,255,255,.72);
2 | @whiteTrans48: rgba(255,255,255,.48);
3 | @mainBackground: #141414;
4 | @darkerBackground: #0a0a0a;
5 | @containerMargin: 3.2rem;
6 | @gutterSize: @containerMargin / 4;
7 | @thatYellow: #caad2d;
8 | @thinBorder: 1px solid #1f1f1f;
9 |
10 | body {
11 | margin: 0;
12 | font-family: 'Montserrat', sans-serif;
13 | background-color: @mainBackground;
14 | color: @whiteTrans72;
15 | }
16 |
17 | .row-gutter {
18 | margin-left: -@gutterSize;
19 | margin-right: -@gutterSize;
20 | }
21 |
22 | .my25em {
23 | margin-top: 2.5em;
24 | margin-bottom: 2.5em;
25 | }
26 |
27 | .p16 {
28 | padding: 1.6em;
29 | }
30 |
31 | .py18 {
32 | padding-top: 1.8em;
33 | padding-bottom: 1.8em;
34 | }
35 |
36 | .py16 {
37 | padding-top: 1.6em;
38 | padding-bottom: 1.6em;
39 | }
40 |
41 | .margb24 {
42 | margin-bottom: 24px;
43 | }
44 |
45 | .gutter-content {
46 | padding-left: @gutterSize;
47 | padding-right: @gutterSize;
48 | }
49 |
50 | .footer-container {
51 | color: @whiteTrans48;
52 | border-top: @thinBorder;
53 | padding-left: @containerMargin;
54 | padding-right: @containerMargin;
55 | background-color: @darkerBackground;
56 | }
57 |
58 | .large-footer {
59 | padding-top: 15px;
60 | font-size: 14px;
61 | }
62 |
63 | .very-footer {
64 | font-size: 12px;
65 | padding-top: 15px;
66 | padding-bottom: 15px;
67 | border-top: @thinBorder;
68 | background-color: @darkerBackground;
69 | }
70 |
71 | .nav-top {
72 | outline: none;
73 | height: 28px;
74 | line-height: 28px;
75 | border-bottom: @thinBorder;
76 | background-color: @darkerBackground;
77 | }
78 |
79 | .right-menu {
80 | float: right;
81 | margin-right: 3%;
82 | }
83 |
84 | a {
85 | font-size: 11px;
86 | -webkit-transition: color .15s cubic-bezier(.35,0,.25,1);
87 | transition: color .15s cubic-bezier(.35,0,.25,1);
88 | text-decoration: none;
89 | color: @whiteTrans48;
90 | margin-left: 12px;
91 | }
92 |
93 | a:active, a:hover {
94 | outline: 0;
95 | color: #fff;
96 | }
97 |
98 | .container {
99 | margin-right: @containerMargin;
100 | margin-left: @containerMargin;
101 | padding-bottom: 30px;
102 | }
103 |
104 | .nav-main a {
105 | color: @whiteTrans72;
106 | font-size: 12px;
107 | letter-spacing: 1px;
108 | }
109 |
110 | .nav-main a:active, .nav-main a:hover {
111 | padding-bottom: 1.8em;
112 | outline: 0;
113 | color: #fff;
114 | right: 100%;
115 | border-style: solid;
116 | border-width: 0px 0px 3px 0px;
117 | border-bottom-color: #caad2d;
118 | -webkit-transition: all .3s cubic-bezier(.35,0,.25,1);
119 | transition: all .3s cubic-bezier(.35,0,.25,1);
120 | }
121 |
122 | .logo {
123 | display: inline-flex;;
124 | width: 65px;
125 | height: 28px;
126 | vertical-align: middle;
127 | margin: 0 auto;
128 | border-width: 0px;
129 | background: url(../img/logo.svg)50% 50% no-repeat;
130 | background-size: 100% auto;
131 | }
132 |
133 | .front-image {
134 | display: flex;
135 | width: 100%;
136 | }
137 |
138 | .background-text {
139 | background: #1f1f1f;
140 | }
141 |
142 |
143 | .movie-title {
144 | font-size: 12px;
145 | line-height: 16px;
146 | color: rgba(255,255,255,.48);
147 | text-transform: uppercase;
148 | }
149 |
150 | .movie-description {
151 | margin: 0 0 24px;
152 | font-size: 12px;
153 | line-height: 20px;
154 | color: rgba(255,255,255,.72);
155 | }
156 |
157 | .movie-tagline {
158 | font-size: 24px;
159 | line-height: 24px;
160 | color: #fff;
161 | margin: 0 0 24px;
162 | }
163 |
164 | .that-yellow {
165 | margin: 0 0 12px;
166 | color: @thatYellow;
167 | }
168 |
169 | .find-out {
170 | letter-spacing: 1px;
171 | font-size: 12px;
172 | text-transform: uppercase;
173 | margin: 0 0 12px;
174 | color: #a99026;
175 | }
176 |
177 | .find-out:hover {
178 | color: @thatYellow;
179 | }
180 |
181 | .border-left {
182 | border-left: 1px solid;
183 | }
184 |
185 | .margin-bottom-end {
186 | margin-bottom: 40px;
187 | }
188 |
--------------------------------------------------------------------------------
/src/photo/components/blob-component.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import Component from 'inferno-component'
3 | import {connect} from 'inferno-redux'
4 | import orderBy from 'lodash/orderBy'
5 | import fetch from '../tvmaze'
6 | import CardComponent from './card-component'
7 |
8 | class BlobComponent extends Component {
9 |
10 | componentWillMount() {
11 | const thiz = this
12 | fetch(0)
13 | .then(response => {
14 | const sortedShows = orderBy(response, [o => {
15 | return o.show.weight && o.show.rating.average > 0 ? o.show.weight : 0
16 | }, o => {
17 | return o.show.rating.average > 0 ? o.show.rating.average : 0
18 | }], ['desc', 'desc'])
19 |
20 | thiz.setState({
21 | shows: sortedShows
22 | })
23 |
24 | thiz.props.store.dispatch({
25 | type: 'SHOWS',
26 | name: sortedShows
27 | })
28 | }).catch(err => {
29 | console.log('Error: ' + err)
30 | })
31 | }
32 |
33 | render() {
34 | if (!this.props.shows) {
35 | return (Loading...
)
36 | }
37 |
38 | return (
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | {this.props.shows[0].show.name} | Season {this.props.shows[0].season} Ep {this.props.shows[0].number}
48 |
49 |
50 | {this.props.shows[0].name}
51 |
52 |
53 | {this.props.shows[0].summary ? this.props.shows[0].summary.replace(/(<([^>]+)>)/ig, '') : this.props.shows[0].show.summary.replace(/(<([^>]+)>)/ig, '') }
54 |
55 |
56 | Find out more
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
)
93 | }
94 | }
95 |
96 | const mapStateToProps = state => ({
97 | shows: state.shows
98 | })
99 |
100 | export default connect(mapStateToProps)(BlobComponent)
101 |
--------------------------------------------------------------------------------
/src/photo/components/card-component.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import Component from 'inferno-component'
3 |
4 | class CardComponent extends Component {
5 | componentDidMount() {
6 | }
7 |
8 | prettyText(show) {
9 | let summary = show.summary ? show.summary : show.show.summary
10 | summary = summary.replace(/(<([^>]+)>)/ig, '')
11 | if (summary.length > 200) {
12 | summary = summary.substring(0, 200) + '...'
13 | }
14 | return summary
15 | }
16 |
17 | render() {
18 | const show = this.props.show
19 | const genres = []
20 | if (show.show.genres && show.show.genres.length > 0) {
21 | for (let i = 0; i < show.show.genres.length; i++) {
22 | genres.push({show.show.genres[i]} )
23 | if (i < show.show.genres.length - 1) {
24 | genres.push( | )
25 | }
26 | }
27 | }
28 | const imageCount = this.props.imageCount
29 | let imageStyles = 'fit-image'
30 | imageStyles = imageCount === 1 ? imageStyles += ' front-image' : imageCount === 2 ? imageStyles += ' two-image' : imageStyles += ' three-image'
31 | return (
32 |
33 |
34 |
35 | {show.show.name} - Season {show.season} Ep {show.number}
36 |
37 | {show.airtime}
38 |
39 |
40 | {genres}
41 |
42 |
43 |
44 |
45 | {show.name}
46 |
47 |
48 | { this.prettyText(show) }
49 |
50 |
51 |
52 | { show.show.network.name }
53 |
54 |
55 | Rating: { show.show.rating.average }
56 |
57 |
58 |
59 | Find out more
60 |
61 |
62 | )
63 | }
64 | }
65 |
66 | export default CardComponent
67 |
--------------------------------------------------------------------------------
/src/photo/components/footer-component.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import Component from 'inferno-component'
3 |
4 | class FooterComponent extends Component {
5 | render() {
6 | return (
7 |
8 |
17 |
18 | ©2017 Some Rights Reserved. Schedules retreived from
TVmaze . This website may contain mature content.
19 |
20 |
21 | )
22 | }
23 | }
24 |
25 | export default FooterComponent
26 |
--------------------------------------------------------------------------------
/src/photo/components/header-component.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import Component from 'inferno-component'
3 | import {connect} from 'inferno-redux'
4 | import orderBy from 'lodash/orderBy'
5 | import fetch from '../tvmaze'
6 |
7 | const DAYS = ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY']
8 |
9 | class HeaderComponent extends Component {
10 | constructor(props) {
11 | super(props)
12 | this.handleClick = this.handleClick.bind(this)
13 | }
14 |
15 | componentDidMount() {
16 | }
17 |
18 | componentWillMount() {
19 | const date = new Date()
20 | this.setState({
21 | today: date.getDay(),
22 | day: date.getDay()
23 | })
24 | }
25 |
26 | handleClick(day) {
27 | this.setState({day})
28 | this.fetchShows()
29 | }
30 |
31 | fetchShows() {
32 | const thiz = this
33 | let shift = 0
34 | if (this.state.day !== this.state.today) {
35 | if (this.state.day - this.state.today < 0) {
36 | shift = 7 + (this.state.day - this.state.today)
37 | } else {
38 | shift = this.state.day - this.state.today
39 | }
40 | }
41 | thiz.props.store.dispatch({
42 | type: 'SHOWS',
43 | name: null
44 | })
45 | fetch(shift)
46 | .then(response => {
47 | const sortedShows = orderBy(response, [o => {
48 | return o.show.weight && o.show.rating.average > 0 ? o.show.weight : 0
49 | }, o => {
50 | return o.show.rating.average > 0 ? o.show.rating.average : 0
51 | }], ['desc', 'desc'])
52 |
53 | thiz.props.store.dispatch({
54 | type: 'SHOWS',
55 | name: sortedShows
56 | })
57 | }).catch(err => {
58 | console.log('Error: ' + err)
59 | })
60 | }
61 |
62 | render() {
63 | const days = []
64 | for (let i = 0; i < DAYS.length; i++) {
65 | const thisDay = DAYS[i]
66 | const thisDayNum = i
67 | days.push(
68 |
76 | {thisDay}
77 |
78 | )
79 | }
80 |
81 | return (
82 |
83 |
84 |
85 | {days}
86 |
87 |
88 | )
89 | }
90 | }
91 |
92 | const mapStateToProps = state => ({
93 | shows: state.shows
94 | })
95 |
96 | export default connect(mapStateToProps)(HeaderComponent)
97 |
--------------------------------------------------------------------------------
/src/photo/components/main-component.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import Component from 'inferno-component'
3 | import FooterComponent from './footer-component'
4 | import TopHeaderComponent from './top-header-component'
5 | import BlobComponent from './blob-component'
6 | import HeaderComponent from './header-component'
7 |
8 | class MainComponent extends Component {
9 | componentDidMount() {
10 | }
11 |
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
)
22 | }
23 | }
24 |
25 | export default MainComponent
26 |
--------------------------------------------------------------------------------
/src/photo/components/top-header-component.js:
--------------------------------------------------------------------------------
1 | import Component from 'inferno-component'
2 | import Inferno from 'inferno'
3 |
4 | class TopHeaderComponent extends Component {
5 | render() {
6 | return (
7 |
8 |
12 |
13 | )
14 | }
15 | }
16 |
17 | export default TopHeaderComponent
18 |
--------------------------------------------------------------------------------
/src/photo/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hirako2000/polypack/1cf9d86c5b194e5cf72b55f95f3eb7bcefca790a/src/photo/favicon.ico
--------------------------------------------------------------------------------
/src/photo/img/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 | Shape
4 | Some Logo
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/photo/index-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/photo/index.js:
--------------------------------------------------------------------------------
1 | import Inferno from 'inferno'
2 | import {Provider} from 'inferno-redux'
3 | import {createStore} from 'redux'
4 | import * as buttons from 'mincss-modules/less/buttons.less'
5 | import * as grid from 'mincss-modules/less/grid.less'
6 | import * as icons from 'mincss-modules/less/icons.less'
7 | import * as navbar from 'mincss-modules/less/navbar.less'
8 | import * as tables from 'mincss-modules/less/tables.less'
9 | import * as forms from 'mincss-modules/less/forms.less'
10 | import * as styles from './styles/styles.less'
11 | import * as logo from './img/logo.svg'
12 | import MainComponent from './components/main-component'
13 |
14 | const store = createStore((state, action) => {
15 | switch (action.type) {
16 | case 'SHOWS':
17 | return {
18 | shows: action.name
19 | }
20 | default:
21 | return {
22 | shows: null
23 | }
24 | }
25 | })
26 |
27 | Inferno.render(
28 |
29 |
30 | , document.getElementById('app')
31 | )
32 |
33 | export {buttons, grid, icons, navbar, tables, forms, styles, logo}
34 |
--------------------------------------------------------------------------------
/src/photo/styles/styles.less:
--------------------------------------------------------------------------------
1 | @whiteTrans72: rgba(255,255,255,.72);
2 | @whiteTrans48: rgba(255,255,255,.48);
3 | @mainBackground: #141414;
4 | @darkerBackground: #0a0a0a;
5 | @containerMargin: 3.2rem;
6 | @gutterSize: @containerMargin / 4;
7 | @thatYellow: #caad2d;
8 | @thinBorder: 1px solid #1f1f1f;
9 | @objectFit: cover;
10 |
11 | body {
12 | margin: 0;
13 | font-family: 'Montserrat', sans-serif;
14 | background-color: @mainBackground;
15 | color: @whiteTrans72;
16 | }
17 |
18 | .float-right {
19 | float: right;
20 | }
21 |
22 | .social {
23 | height: 3em;
24 | fill: @whiteTrans48;
25 | }
26 |
27 | .social:hover {
28 | height: 3em;
29 | fill: @whiteTrans72;
30 | }
31 |
32 | .row-gutter {
33 | margin-left: -@gutterSize;
34 | margin-right: -@gutterSize;
35 | }
36 |
37 | .my25em {
38 | margin-top: 2.5em;
39 | margin-bottom: 2.5em;
40 | }
41 |
42 | .p16 {
43 | padding: 1.6em;
44 | }
45 |
46 | .py18 {
47 | padding-top: 1.8em;
48 | padding-bottom: 1.8em;
49 | }
50 |
51 | .py16 {
52 | padding-top: 1.6em;
53 | padding-bottom: 1.6em;
54 | }
55 |
56 | .pt14 {
57 | padding-top: 1.4em;
58 | }
59 |
60 | .pb8 {
61 | padding-bottom: 0.8em;
62 | }
63 |
64 | .margb24 {
65 | margin-bottom: 24px;
66 | }
67 |
68 | .gutter-content {
69 | padding-left: @gutterSize;
70 | padding-right: @gutterSize;
71 | }
72 |
73 | .footer-container {
74 | color: @whiteTrans48;
75 | border-top: @thinBorder;
76 | padding-left: @containerMargin;
77 | padding-right: @containerMargin;
78 | background-color: @darkerBackground;
79 | }
80 |
81 | .large-footer {
82 | padding-top: 15px;
83 | font-size: 14px;
84 | }
85 |
86 | .very-footer {
87 | font-size: 0.6em;
88 | padding-top: 1em;
89 | padding-bottom: 1em;
90 | background-color: @darkerBackground;
91 | }
92 |
93 | .very-footer a {
94 | font-size: 1em;
95 | text-decoration: none;
96 | color: rgba(255, 255, 255, 0.68);
97 | margin-left: 0;
98 | }
99 |
100 | .row a {
101 | font-size: 1em;
102 | }
103 |
104 | .nav-top {
105 | outline: none;
106 | height: 28px;
107 | line-height: 28px;
108 | border-bottom: @thinBorder;
109 | background-color: @darkerBackground;
110 | }
111 |
112 | .right-menu {
113 | float: right;
114 | margin-right: 3%;
115 | }
116 |
117 | a {
118 | font-size: 11px;
119 | -webkit-transition: color .15s cubic-bezier(.35,0,.25,1);
120 | transition: color .15s cubic-bezier(.35,0,.25,1);
121 | text-decoration: none;
122 | color: @whiteTrans48;
123 | margin-left: 12px;
124 | }
125 |
126 | a:active, a:hover {
127 | outline: 0;
128 | color: #fff;
129 | }
130 |
131 | .container {
132 | margin-right: @containerMargin;
133 | margin-left: @containerMargin;
134 | padding-bottom: 30px;
135 | }
136 |
137 | .nav-main a {
138 | color: @whiteTrans72;
139 | font-size: 12px;
140 | letter-spacing: 1px;
141 | }
142 |
143 | .nav-main a:active, .nav-main a:hover {
144 | outline: 0;
145 | color: #fff;
146 | right: 100%;
147 | }
148 |
149 | .underline {
150 | padding-bottom: 1.8em;
151 | outline: 0;
152 | color: #fff;
153 | right: 100%;
154 | border-style: solid;
155 | border-width: 0 0 3px;
156 | border-bottom-color: #caad2d;
157 | -webkit-transition: all .3s cubic-bezier(.35,0,.25,1);
158 | transition: all .3s cubic-bezier(.35,0,.25,1);
159 | }
160 |
161 | .logo {
162 | display: inline-flex;;
163 | width: 65px;
164 | height: 28px;
165 | vertical-align: middle;
166 | margin: 0 auto;
167 | border-width: 0px;
168 | background: url(../img/logo.svg)50% 50% no-repeat;
169 | background-size: 100% auto;
170 | }
171 |
172 | .fit-image {
173 | display: flex;
174 | width: 100%;
175 | }
176 |
177 | @media (max-width: 870px) {
178 | .front-image {
179 | object-fit: @objectFit;
180 | min-height: 450px;
181 | max-height: 450px;
182 | }
183 |
184 | .two-image {
185 | object-fit: @objectFit;
186 | min-height: 350px;
187 | max-height: 350px;
188 | }
189 |
190 | .three-image {
191 | object-fit: @objectFit;
192 | max-height: 350px;
193 | max-height: 350px;
194 | }
195 | }
196 |
197 | @media (min-width: 870px) {
198 | .front-image {
199 | object-fit: @objectFit;
200 | min-height: 450px;
201 | max-height: 450px;
202 | }
203 |
204 | .two-image {
205 | object-fit: @objectFit;
206 | min-height: 300px;
207 | max-height: 300px;
208 | }
209 |
210 | .three-image {
211 | object-fit: @objectFit;
212 | min-height: 200px;
213 | max-height: 200px;
214 | }
215 | }
216 |
217 | .background-text {
218 | background: #1f1f1f;
219 | }
220 |
221 | .genres {
222 | font-size: 0.6rem;
223 | color: @whiteTrans48;
224 | text-transform: uppercase;
225 | }
226 |
227 | .airtime {
228 | float: right;
229 | }
230 |
231 | .movie-title {
232 | font-size: 12px;
233 | line-height: 16px;
234 | color: @whiteTrans48;
235 | text-transform: uppercase;
236 | }
237 |
238 | .movie-description {
239 | text-align: justify;
240 | margin: 0 0 24px;
241 | font-size: 12px;
242 | line-height: 20px;
243 | color: @whiteTrans72;
244 | }
245 |
246 | .movie-tagline {
247 | font-size: 24px;
248 | line-height: 24px;
249 | color: #fff;
250 | margin: 0 0 24px;
251 | }
252 |
253 | .that-yellow {
254 | margin: 0 0 12px;
255 | color: @thatYellow;
256 | }
257 |
258 | .find-out {
259 | letter-spacing: 1px;
260 | font-size: 12px;
261 | text-transform: uppercase;
262 | margin: 0 0 12px;
263 | color: #a99026;
264 | }
265 |
266 | .find-out:hover {
267 | color: @thatYellow;
268 | }
269 |
270 | .border-left {
271 | border-left: 1px solid;
272 | }
273 |
274 | .margin-bottom-end {
275 | margin-bottom: 40px;
276 | }
277 |
278 | .loader,
279 | .loader:before,
280 | .loader:after {
281 | background: #ffffff;
282 | -webkit-animation: load1 1s infinite ease-in-out;
283 | animation: load1 1s infinite ease-in-out;
284 | width: 1em;
285 | height: 4em;
286 | }
287 |
288 | .loader {
289 | height: 600px;
290 | color: #ffffff;
291 | text-indent: -9999em;
292 | margin: 88px auto;
293 | position: relative;
294 | font-size: 11px;
295 | -webkit-transform: translateZ(0);
296 | -ms-transform: translateZ(0);
297 | transform: translateZ(0);
298 | -webkit-animation-delay: -0.16s;
299 | animation-delay: -0.16s;
300 | }
301 | .loader:before,
302 | .loader:after {
303 | position: absolute;
304 | top: 0;
305 | content: '';
306 | }
307 | .loader:before {
308 | left: -1.5em;
309 | -webkit-animation-delay: -0.32s;
310 | animation-delay: -0.32s;
311 | }
312 | .loader:after {
313 | left: 1.5em;
314 | }
315 | @-webkit-keyframes load1 {
316 | 0%,
317 | 80%,
318 | 100% {
319 | box-shadow: 0 0;
320 | height: 4em;
321 | }
322 | 40% {
323 | box-shadow: 0 -2em;
324 | height: 5em;
325 | }
326 | }
327 | @keyframes load1 {
328 | 0%,
329 | 80%,
330 | 100% {
331 | box-shadow: 0 0;
332 | height: 4em;
333 | }
334 | 40% {
335 | box-shadow: 0 -2em;
336 | height: 5em;
337 | }
338 | }
339 |
340 | /* Fad in */
341 | .fade-in {
342 | margin-top: 25px;
343 | font-size: 21px;
344 | -webkit-animation: fadein 2s; /* Safari, Chrome and Opera > 12.1 */
345 | -ms-animation: fadein 2s; /* Internet Explorer */
346 | animation: fadein 2s;
347 | }
348 |
349 | @keyframes fadein {
350 | from { opacity: 0; }
351 | to { opacity: 1; }
352 | }
353 |
354 | /* Safari, Chrome and Opera > 12.1 */
355 | @-webkit-keyframes fadein {
356 | from { opacity: 0; }
357 | to { opacity: 1; }
358 | }
359 |
360 | /* Internet Explorer */
361 | @-ms-keyframes fadein {
362 | from { opacity: 0; }
363 | to { opacity: 1; }
364 | }
365 |
--------------------------------------------------------------------------------
/src/photo/tvmaze.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import fecha from 'fecha'
4 |
5 | const date = new Date()
6 | date.setDate(date.getDate() - 0)
7 | const API_URL = 'http://api.tvmaze.com/schedule?country=US&date='
8 |
9 | const fetch = dayShift => new Promise((resolve, reject) => {
10 | const date = new Date()
11 | dayShift = dayShift ? dayShift : 0
12 | date.setDate(date.getDate() + dayShift)
13 | const formattedDate = fecha.format(date, 'YYYY-MM-DD')
14 | const urlWithDate = API_URL + formattedDate
15 | const httpReq = new XMLHttpRequest()
16 | httpReq.open('GET', urlWithDate.replace(/\s/ig, '%20'), true)
17 | httpReq.onreadystatechange = function () {
18 | if (httpReq.readyState !== 4) {
19 | return
20 | }
21 | if (httpReq.status !== 200) {
22 | reject(new Error('Unexpected HTTP status code: ' + httpReq.status))
23 | }
24 | resolve(JSON.parse(httpReq.responseText))
25 | }
26 | httpReq.send()
27 | })
28 |
29 | export default fetch
30 |
--------------------------------------------------------------------------------
/src/purecss/index-template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | #
52 | Make
53 | Model
54 | Year
55 |
56 |
57 |
58 |
59 |
60 | 1
61 | Honda
62 | Accord
63 | 2009
64 |
65 |
66 |
67 | 2
68 | Toyota
69 | Camry
70 | 2012
71 |
72 |
73 |
74 | 3
75 | Hyundai
76 | Elantra
77 | 2010
78 |
79 |
80 |
81 | 4
82 | Ford
83 | Focus
84 | 2008
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/purecss/index.js:
--------------------------------------------------------------------------------
1 | import * as base from 'purecss/build/base.css'
2 | import * as buttons from 'purecss/build/buttons.css'
3 | import * as tables from 'purecss/build/tables.css'
4 | import * as menus from 'purecss/build/menus.css'
5 | import * as grids from 'purecss/build/grids.css'
6 | import * as styles from './styles/styles.css'
7 |
8 | export {base, buttons, tables, menus, grids, styles}
9 |
--------------------------------------------------------------------------------
/src/purecss/styles/styles.css:
--------------------------------------------------------------------------------
1 | .header {
2 | text-align: center;
3 | }
4 |
5 | .relaxed {
6 | padding: 20px;
7 | }
8 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const CompressionPlugin = require("compression-webpack-plugin")
4 | const ExtractTextPlugin = require("extract-text-webpack-plugin")
5 | const HtmlWebpackPlugin = require('html-webpack-plugin')
6 |
7 | const sourcePath = path.join(__dirname, './src')
8 |
9 | module.exports = function (env) {
10 | const nodeEnv = env && env.prod ? 'production' : 'development'
11 | const isProd = nodeEnv === 'production'
12 |
13 | const plugins = [
14 | new webpack.optimize.CommonsChunkPlugin({
15 | names: ['inferno.vendor'],
16 | chunks: ['inferno'],
17 | minChunks: function (module) {
18 | return isExternal(module)
19 | }
20 | }),
21 | new webpack.optimize.CommonsChunkPlugin({
22 | name: 'purecss.vendor',
23 | chunks: ['purecss'],
24 | minChunks: function (module) {
25 | return isExternal(module)
26 | }
27 | }),
28 | new webpack.optimize.CommonsChunkPlugin({
29 | name: 'mincss.vendor',
30 | chunks: ['mincss'],
31 | minChunks: function (module) {
32 | return isExternal(module)
33 | }
34 | }),
35 | new webpack.optimize.CommonsChunkPlugin({
36 | name: 'photo.vendor',
37 | chunks: ['photo'],
38 | minChunks: function (module) {
39 | return isExternal(module)
40 | }
41 | }),
42 | new webpack.DefinePlugin({
43 | 'process.env': {NODE_ENV: JSON.stringify(nodeEnv)}
44 | }),
45 | new webpack.NamedModulesPlugin(),
46 | new HtmlWebpackPlugin({
47 | filename: 'inferno.html',
48 | title: 'Inferno',
49 | template: 'inferno/index-template.html',
50 | chunks: ['inferno.vendor', 'inferno']
51 | }),
52 | new HtmlWebpackPlugin({
53 | filename: 'purecss.html',
54 | title: 'PureCSS',
55 | template: 'purecss/index-template.html',
56 | chunks: ['purecss.vendor', 'purecss']
57 | }),
58 | new HtmlWebpackPlugin({
59 | filename: 'mincss.html',
60 | title: 'MINCSS',
61 | template: 'mincss/index-template.html',
62 | chunks: ['mincss.vendor', 'mincss']
63 | }),
64 | new HtmlWebpackPlugin({
65 | filename: 'photo.html',
66 | title: 'Photo',
67 | template: 'photo/index-template.html',
68 | chunks: ['photo.vendor', 'photo']
69 | })
70 | ]
71 |
72 | if (isProd) {
73 | plugins.push(
74 | new webpack.LoaderOptionsPlugin({
75 | minimize: true,
76 | debug: false
77 | }),
78 | new webpack.optimize.UglifyJsPlugin({
79 | compress: {
80 | warnings: false
81 | },
82 | output: {
83 | comments: false
84 | },
85 | sourceMap: true
86 | }),
87 | new CompressionPlugin({
88 | asset: '[path].gz[query]',
89 | algorithm: 'gzip',
90 | test: /\.js$|\.css$|\.html$|\.eot$|\.svg$|\.ttf$|\.woff$/,
91 | threshold: 1024,
92 | minRatio: 0.8
93 | }),
94 | new ExtractTextPlugin('[name].css'),
95 | new webpack.optimize.ModuleConcatenationPlugin()
96 | )
97 | } else {
98 | plugins.push(
99 | new webpack.HotModuleReplacementPlugin()
100 | )
101 | }
102 |
103 | return {
104 | devtool: isProd ? 'source-map' : 'eval',
105 | context: sourcePath,
106 | entry: {
107 | inferno: './inferno/index.js',
108 | purecss: './purecss/index.js',
109 | mincss: './mincss/index.js',
110 | photo: './photo/index.js'
111 | },
112 | output: {
113 | path: __dirname + '/static',
114 | filename: '[name].js'
115 | },
116 | module: {
117 | rules: [
118 | {
119 | test: /\.html$/,
120 | use: {
121 | loader: 'html-loader',
122 | query: {
123 | name: '[name].[ext]'
124 | }
125 | }
126 | },
127 | {
128 | test: /\.less$/,
129 | use: isProd ? lessExtractTextLoader() : lessNonExtractTextLoader()
130 | },
131 | {
132 | test: /\.css$/,
133 | use: isProd ? extractTextLoader() : nonExtractTextLoader()
134 | },
135 | {
136 | test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
137 | loader: isProd ? 'file-loader?limit=10000&mimetype=application/font-woff' : 'url-loader?limit=10000&mimetype=application/font-woff'
138 | },
139 | {
140 | test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
141 | loader: isProd ? 'file-loader' : 'url-loader'
142 | },
143 | {
144 | test: /\.(jpg|jpeg|png)$/,
145 | loader: isProd ? 'file-loader' : 'url-loader'
146 | },
147 | {
148 | test: /\.(js|jsx)$/,
149 | use: [
150 | 'babel-loader'
151 | ]
152 | }
153 | ]
154 | },
155 | resolve: {
156 | extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
157 | modules: [
158 | path.resolve(__dirname, 'node_modules'),
159 | sourcePath
160 | ]
161 | },
162 |
163 | plugins,
164 |
165 | performance: isProd && {
166 | maxAssetSize: 100000,
167 | maxEntrypointSize: 100000,
168 | hints: 'warning'
169 | },
170 |
171 | stats: {
172 | colors: {
173 | green: '\u001b[32m'
174 | }
175 | },
176 |
177 | devServer: {
178 | contentBase: './src',
179 | historyApiFallback: true,
180 | port: 3000,
181 | compress: isProd,
182 | inline: !isProd,
183 | hot: !isProd,
184 | stats: {
185 | assets: true,
186 | children: false,
187 | chunks: false,
188 | hash: false,
189 | modules: false,
190 | publicPath: false,
191 | timings: true,
192 | version: false,
193 | warnings: true,
194 | colors: {
195 | green: '\u001b[32m'
196 | }
197 | }
198 | }
199 | }
200 | }
201 |
202 | function isExternal(module) {
203 | const userRequest = module.userRequest
204 |
205 | if (typeof userRequest !== 'string') {
206 | return false
207 | }
208 |
209 | return userRequest.indexOf('bower_components') >= 0 ||
210 | userRequest.indexOf('node_modules') >= 0 ||
211 | userRequest.indexOf('libraries') >= 0
212 | }
213 |
214 | function nonExtractTextLoader() {
215 | return [
216 | 'style-loader',
217 | 'css-loader?sourceMap'
218 | ]
219 | }
220 |
221 | function lessNonExtractTextLoader() {
222 | return [
223 | 'style-loader',
224 | 'css-loader?sourceMap',
225 | 'less-loader?sourceMap'
226 | ]
227 | }
228 |
229 | function extractTextLoader() {
230 | return ExtractTextPlugin.extract({
231 | fallback: 'style-loader', use: 'css-loader'
232 | })
233 | }
234 |
235 | function lessExtractTextLoader() {
236 | return ExtractTextPlugin.extract({
237 | fallback: 'style-loader', use: 'css-loader!less-loader'
238 | })
239 | }
240 |
--------------------------------------------------------------------------------