├── .gitignore ├── LICENSE ├── README.md ├── assets-src ├── apple-touch-icon.png └── web-icon.png ├── babel.config.js ├── build ├── build.js └── webpack.config.js ├── docs ├── css │ ├── app.css │ └── app.css.map ├── fonts │ ├── Framework7Icons-Regular.eot │ ├── Framework7Icons-Regular.ttf │ ├── Framework7Icons-Regular.woff │ ├── Framework7Icons-Regular.woff2 │ ├── MaterialIcons-Regular.eot │ ├── MaterialIcons-Regular.ttf │ ├── MaterialIcons-Regular.woff │ └── MaterialIcons-Regular.woff2 ├── index.html ├── js │ ├── app.js │ └── app.js.map ├── manifest.json ├── precache-manifest.ee64b368b11e56fbe88233e61274b033.js ├── service-worker.js └── static │ └── icons │ ├── 128x128.png │ ├── 144x144.png │ ├── 152x152.png │ ├── 192x192.png │ ├── 256x256.png │ ├── 512x512.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── favicon.png ├── lighthouse-score.png ├── package.json ├── postcss.config.js └── src ├── .DS_Store ├── css ├── app.css └── icons.css ├── fonts ├── Framework7Icons-Regular.eot ├── Framework7Icons-Regular.ttf ├── Framework7Icons-Regular.woff ├── Framework7Icons-Regular.woff2 ├── MaterialIcons-Regular.eot ├── MaterialIcons-Regular.ttf ├── MaterialIcons-Regular.woff └── MaterialIcons-Regular.woff2 ├── index.html ├── js ├── app.js └── routes.js ├── manifest.json ├── pages ├── 404.f7.html ├── about.f7.html ├── stories.f7.html └── story.f7.html ├── service-worker.js ├── static ├── .DS_Store └── icons │ ├── 128x128.png │ ├── 144x144.png │ ├── 152x152.png │ ├── 192x192.png │ ├── 256x256.png │ ├── 512x512.png │ ├── apple-touch-icon.png │ ├── favicon.ico │ └── favicon.png └── template7-helpers-list.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json 3 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Guillaume Biton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HackerNews7 2 | =========== 3 | 4 | Another Hacker News Reader powered by [Framework7](https://github.com/nolimits4web/Framework7) 5 | 6 | About 7 | ----- 8 | This is a demo app to show how [Framework7](https://github.com/nolimits4web/Framework7) makes it easy to develop hybrid apps. 9 | 10 | Features 11 | -------- 12 | 13 | Framework7 v4 features demonstrate in component pages. 14 | 15 | This demo is developped using [Framework Command-Line Interface](http://framework7.io/cli/). 16 | 17 | ## stories.html 18 | 19 | - [Tabs](http://framework7.io/docs/tabs.html) 20 | - [Tabbar](http://framework7.io/docs/toolbar-tabbar.html) 21 | - [Infinite scroll](http://framework7.io/docs/infinite-scroll.html) 22 | - [Template7 helpers](http://idangero.us/template7) 23 | - [virtual Dom](http://framework7.io/docs/router-component.html#virtual-dom) 24 | - [Master details](http://framework7.io/docs/view.html#master-detail) 25 | 26 | ## storie.html 27 | 28 | - [Messages](http://framework7.io/docs/messages.html) 29 | - [Template7 partial](http://idangero.us/template7) 30 | - [virtual Dom](http://framework7.io/docs/router-component.html#virtual-dom) 31 | 32 | License 33 | ------- 34 | 35 | Licensed under the [MIT License](https://github.com/GuillaumeBiton/HackerNews7/raw/master/LICENSE) 36 | 37 | PWA 38 | --- 39 | 40 | ![LightHouse Score](https://github.com/GuillaumeBiton/HackerNews7/raw/master/lighthouse-score.png) 41 | 42 | Thanks 43 | ------ 44 | 45 | To all who contribute or want to contribute. -------------------------------------------------------------------------------- /assets-src/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/assets-src/apple-touch-icon.png -------------------------------------------------------------------------------- /assets-src/web-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/assets-src/web-icon.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | ['@babel/preset-env', { 4 | modules: false, 5 | targets: { 6 | browsers: [ 7 | 'Android >= 5', 8 | 'IOS >= 9.3', 9 | 'Edge >= 15', 10 | 'Safari >= 9.1', 11 | 'Chrome >= 49', 12 | 'Firefox >= 31', 13 | 'Samsung >= 5', 14 | ], 15 | }, 16 | }], 17 | ], 18 | plugins: [ 19 | // "@babel/plugin-transform-runtime", 20 | '@babel/plugin-syntax-dynamic-import', 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /build/build.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const ora = require('ora'); 3 | const rm = require('rimraf'); 4 | const chalk = require('chalk'); 5 | const config = require('./webpack.config.js'); 6 | 7 | const env = process.env.NODE_ENV || 'development'; 8 | const target = process.env.TARGET || 'web'; 9 | const isCordova = target === 'cordova' 10 | 11 | const spinner = ora(env === 'production' ? 'building for production...' : 'building development version...'); 12 | spinner.start(); 13 | 14 | rm(isCordova ? './cordova/www' : './www/', (removeErr) => { 15 | if (removeErr) throw removeErr; 16 | 17 | webpack(config, (err, stats) => { 18 | if (err) throw err; 19 | spinner.stop(); 20 | 21 | process.stdout.write(`${stats.toString({ 22 | colors: true, 23 | modules: false, 24 | children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build. 25 | chunks: false, 26 | chunkModules: false, 27 | })}\n\n`); 28 | 29 | if (stats.hasErrors()) { 30 | console.log(chalk.red('Build failed with errors.\n')); 31 | process.exit(1); 32 | } 33 | 34 | console.log(chalk.cyan('Build complete.\n')); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /build/webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const CopyWebpackPlugin = require('copy-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 6 | const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin'); 7 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 8 | const WorkboxPlugin = require('workbox-webpack-plugin'); 9 | 10 | const path = require('path'); 11 | 12 | function resolvePath(dir) { 13 | return path.join(__dirname, '..', dir); 14 | } 15 | 16 | const env = process.env.NODE_ENV || 'development'; 17 | const target = process.env.TARGET || 'web'; 18 | 19 | 20 | module.exports = { 21 | mode: env, 22 | entry: [ 23 | './src/js/app.js', 24 | ], 25 | output: { 26 | path: resolvePath('www'), 27 | filename: 'js/app.js', 28 | publicPath: '', 29 | }, 30 | resolve: { 31 | extensions: ['.js', '.vue', '.json'], 32 | alias: { 33 | vue$: 'vue/dist/vue.esm.js', 34 | '@': resolvePath('src'), 35 | }, 36 | }, 37 | devtool: env === 'production' ? 'source-map' : 'eval', 38 | devServer: { 39 | hot: true, 40 | open: true, 41 | compress: true, 42 | contentBase: '/www/', 43 | disableHostCheck: true, 44 | watchOptions: { 45 | poll: true, 46 | }, 47 | }, 48 | module: { 49 | rules: [ 50 | { 51 | test: /\.(js|jsx)$/, 52 | use: 'babel-loader', 53 | include: [ 54 | resolvePath('src'), 55 | resolvePath('node_modules/framework7'), 56 | resolvePath('node_modules/framework7-vue'), 57 | resolvePath('node_modules/framework7-react'), 58 | resolvePath('node_modules/template7'), 59 | resolvePath('node_modules/dom7'), 60 | resolvePath('node_modules/ssr-window'), 61 | ], 62 | }, 63 | { 64 | test: /\.f7.html$/, 65 | use: [ 66 | 'babel-loader', 67 | { 68 | loader: 'framework7-component-loader', 69 | options: { 70 | helpersPath: './src/template7-helpers-list.js', 71 | }, 72 | }, 73 | ], 74 | }, 75 | 76 | { 77 | test: /\.css$/, 78 | use: [ 79 | (env === 'development' ? 'style-loader' : { 80 | loader: MiniCssExtractPlugin.loader, 81 | options: { 82 | publicPath: '../' 83 | } 84 | }), 85 | 'css-loader', 86 | 'postcss-loader', 87 | ], 88 | }, 89 | { 90 | test: /\.styl(us)?$/, 91 | use: [ 92 | (env === 'development' ? 'style-loader' : { 93 | loader: MiniCssExtractPlugin.loader, 94 | options: { 95 | publicPath: '../' 96 | } 97 | }), 98 | 'css-loader', 99 | 'postcss-loader', 100 | 'stylus-loader', 101 | ], 102 | }, 103 | { 104 | test: /\.less$/, 105 | use: [ 106 | (env === 'development' ? 'style-loader' : { 107 | loader: MiniCssExtractPlugin.loader, 108 | options: { 109 | publicPath: '../' 110 | } 111 | }), 112 | 'css-loader', 113 | 'postcss-loader', 114 | 'less-loader', 115 | ], 116 | }, 117 | { 118 | test: /\.(sa|sc)ss$/, 119 | use: [ 120 | (env === 'development' ? 'style-loader' : { 121 | loader: MiniCssExtractPlugin.loader, 122 | options: { 123 | publicPath: '../' 124 | } 125 | }), 126 | 'css-loader', 127 | 'postcss-loader', 128 | 'sass-loader', 129 | ], 130 | }, 131 | { 132 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 133 | loader: 'url-loader', 134 | options: { 135 | limit: 10000, 136 | name: 'images/[name].[ext]', 137 | }, 138 | }, 139 | { 140 | test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, 141 | loader: 'url-loader', 142 | options: { 143 | limit: 10000, 144 | name: 'media/[name].[ext]', 145 | }, 146 | }, 147 | { 148 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 149 | loader: 'url-loader', 150 | options: { 151 | limit: 10000, 152 | name: 'fonts/[name].[ext]', 153 | }, 154 | }, 155 | ], 156 | }, 157 | plugins: [ 158 | new webpack.DefinePlugin({ 159 | 'process.env.NODE_ENV': JSON.stringify(env), 160 | 'process.env.TARGET': JSON.stringify(target), 161 | }), 162 | 163 | ...(env === 'production' ? [ 164 | // Production only plugins 165 | new UglifyJsPlugin({ 166 | uglifyOptions: { 167 | compress: { 168 | warnings: false, 169 | }, 170 | }, 171 | sourceMap: true, 172 | parallel: true, 173 | }), 174 | new OptimizeCSSPlugin({ 175 | cssProcessorOptions: { 176 | safe: true, 177 | map: { inline: false }, 178 | }, 179 | }), 180 | new webpack.optimize.ModuleConcatenationPlugin(), 181 | ] : [ 182 | // Development only plugins 183 | new webpack.HotModuleReplacementPlugin(), 184 | new webpack.NamedModulesPlugin(), 185 | ]), 186 | new HtmlWebpackPlugin({ 187 | filename: './index.html', 188 | template: './src/index.html', 189 | inject: true, 190 | minify: env === 'production' ? { 191 | collapseWhitespace: true, 192 | removeComments: true, 193 | removeRedundantAttributes: true, 194 | removeScriptTypeAttributes: true, 195 | removeStyleLinkTypeAttributes: true, 196 | useShortDoctype: true 197 | } : false, 198 | }), 199 | new MiniCssExtractPlugin({ 200 | filename: 'css/app.css', 201 | }), 202 | new CopyWebpackPlugin([ 203 | { 204 | from: resolvePath('src/static'), 205 | to: resolvePath('www/static'), 206 | }, 207 | { 208 | from: resolvePath('src/manifest.json'), 209 | to: resolvePath('www/manifest.json'), 210 | }, 211 | ]), 212 | 213 | new WorkboxPlugin.InjectManifest({ 214 | swSrc: resolvePath('src/service-worker.js'), 215 | }), 216 | ], 217 | }; -------------------------------------------------------------------------------- /docs/fonts/Framework7Icons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/Framework7Icons-Regular.eot -------------------------------------------------------------------------------- /docs/fonts/Framework7Icons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/Framework7Icons-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/Framework7Icons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/Framework7Icons-Regular.woff -------------------------------------------------------------------------------- /docs/fonts/Framework7Icons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/Framework7Icons-Regular.woff2 -------------------------------------------------------------------------------- /docs/fonts/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /docs/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /docs/fonts/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /docs/fonts/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/fonts/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | hackernews7
-------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hackernews7", 3 | "short_name": "hn7", 4 | "description": "Framework7 HackerNews web app", 5 | "lang": "en-US", 6 | "start_url": "/HackerNews7/", 7 | "display": "standalone", 8 | "background_color": "#FF6B22", 9 | "theme_color": "#FF6B22", 10 | "icons": [ 11 | { 12 | "src": "/static/icons/128x128.png", 13 | "sizes": "128x128", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "/static/icons/144x144.png", 18 | "sizes": "144x144", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "/static/icons/152x152.png", 23 | "sizes": "152x152", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "/static/icons/192x192.png", 28 | "sizes": "192x192", 29 | "type": "image/png" 30 | }, 31 | { 32 | "src": "/static/icons/256x256.png", 33 | "sizes": "256x256", 34 | "type": "image/png" 35 | }, 36 | { 37 | "src": "/static/icons/512x512.png", 38 | "sizes": "512x512", 39 | "type": "image/png" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /docs/precache-manifest.ee64b368b11e56fbe88233e61274b033.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "580b1d9ab465c47cb9b927fd01664225", 4 | "url": "./index.html" 5 | }, 6 | { 7 | "revision": "a0f566ab8d6721329c14", 8 | "url": "css/app.css" 9 | }, 10 | { 11 | "revision": "28db829912bb402df5b1e6fb16f1908c", 12 | "url": "fonts/Framework7Icons-Regular.eot" 13 | }, 14 | { 15 | "revision": "111371010ef70bbcf7e6968abc8e2fb2", 16 | "url": "fonts/Framework7Icons-Regular.ttf" 17 | }, 18 | { 19 | "revision": "5fce7c1238bad823bee064bd127fe4cd", 20 | "url": "fonts/Framework7Icons-Regular.woff" 21 | }, 22 | { 23 | "revision": "19158ff09eb907432a7ccacd074ef9d5", 24 | "url": "fonts/Framework7Icons-Regular.woff2" 25 | }, 26 | { 27 | "revision": "e79bfd88537def476913f3ed52f4f4b3", 28 | "url": "fonts/MaterialIcons-Regular.eot" 29 | }, 30 | { 31 | "revision": "a37b0c01c0baf1888ca812cc0508f6e2", 32 | "url": "fonts/MaterialIcons-Regular.ttf" 33 | }, 34 | { 35 | "revision": "012cf6a10129e2275d79d6adac7f3b02", 36 | "url": "fonts/MaterialIcons-Regular.woff" 37 | }, 38 | { 39 | "revision": "570eb83859dc23dd0eec423a49e147fe", 40 | "url": "fonts/MaterialIcons-Regular.woff2" 41 | }, 42 | { 43 | "revision": "a0f566ab8d6721329c14", 44 | "url": "js/app.js" 45 | }, 46 | { 47 | "revision": "c2ac2c600888eebb2eb57f8b310bfec6", 48 | "url": "manifest.json" 49 | }, 50 | { 51 | "revision": "436babe476e12a14eac928bc1d47cdfc", 52 | "url": "static/.DS_Store" 53 | }, 54 | { 55 | "revision": "4a30eea30e507a8122bbe44c05233fdd", 56 | "url": "static/icons/128x128.png" 57 | }, 58 | { 59 | "revision": "b5147a157dbee1b411bd9de281896ae5", 60 | "url": "static/icons/144x144.png" 61 | }, 62 | { 63 | "revision": "b174b0ec82db4b8ea3c4e5fb7a41cda9", 64 | "url": "static/icons/152x152.png" 65 | }, 66 | { 67 | "revision": "956df353394a14efbdae3c58150d16c8", 68 | "url": "static/icons/192x192.png" 69 | }, 70 | { 71 | "revision": "08900e5fb42c91704fbf5a01796b3e94", 72 | "url": "static/icons/256x256.png" 73 | }, 74 | { 75 | "revision": "fdb0da737b309ae166828b5bb8f0803d", 76 | "url": "static/icons/512x512.png" 77 | }, 78 | { 79 | "revision": "56a6f087b2509df23805162066e27c3f", 80 | "url": "static/icons/apple-touch-icon.png" 81 | }, 82 | { 83 | "revision": "84b7172c8a57f9b721c3fd60c217280b", 84 | "url": "static/icons/favicon.ico" 85 | }, 86 | { 87 | "revision": "4a30eea30e507a8122bbe44c05233fdd", 88 | "url": "static/icons/favicon.png" 89 | } 90 | ]); -------------------------------------------------------------------------------- /docs/service-worker.js: -------------------------------------------------------------------------------- 1 | importScripts("precache-manifest.ee64b368b11e56fbe88233e61274b033.js", "https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js"); 2 | 3 | // manifest import and workbox imports will be autogenerated by webpack 4 | workbox.precaching.precacheAndRoute(self.__precacheManifest || []); 5 | -------------------------------------------------------------------------------- /docs/static/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/128x128.png -------------------------------------------------------------------------------- /docs/static/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/144x144.png -------------------------------------------------------------------------------- /docs/static/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/152x152.png -------------------------------------------------------------------------------- /docs/static/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/192x192.png -------------------------------------------------------------------------------- /docs/static/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/256x256.png -------------------------------------------------------------------------------- /docs/static/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/512x512.png -------------------------------------------------------------------------------- /docs/static/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /docs/static/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/favicon.ico -------------------------------------------------------------------------------- /docs/static/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/docs/static/icons/favicon.png -------------------------------------------------------------------------------- /lighthouse-score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/lighthouse-score.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hackernews7", 3 | "private": true, 4 | "version": "5.0.0-beta", 5 | "description": "Framework7 HackerNews web app", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://guillaumebiton.github.com/HackerNews7.git" 9 | }, 10 | "license": "MIT", 11 | "keywords": [ 12 | "Hackernews", 13 | "Framework7", 14 | "webapp", 15 | "html5" 16 | ], 17 | "authors": [ 18 | "guillaumebiton ", 19 | "Vladimir Kharlampidi" 20 | ], 21 | "bugs": { 22 | "url": "https://guillaumebiton.github.com/HackerNews7/issues" 23 | }, 24 | "homepage": "https://guillaumebiton.github.com/HackerNews7", 25 | "framework7": { 26 | "cwd": "/Users/guillaumebiton/Downloads/hn7", 27 | "type": [ 28 | "web", 29 | "pwa" 30 | ], 31 | "name": "hackernews7", 32 | "framework": "core", 33 | "template": "single-view", 34 | "bundler": "webpack", 35 | "cssPreProcessor": false, 36 | "customColor": true, 37 | "color": "#ff6b22" 38 | }, 39 | "scripts": { 40 | "build-prod": "cross-env NODE_ENV=production node ./build/build.js", 41 | "dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.config.js", 42 | "start": "npm run dev" 43 | }, 44 | "browserslist": [ 45 | "Android >= 5", 46 | "IOS >= 9.3", 47 | "Edge >= 15", 48 | "Safari >= 9.1", 49 | "Chrome >= 49", 50 | "Firefox >= 31", 51 | "Samsung >= 5" 52 | ], 53 | "dependencies": { 54 | "dom7": "^2.1.3", 55 | "framework7": "^5.0.4", 56 | "framework7-icons": "^2.3.1", 57 | "template7": "^1.4.2" 58 | }, 59 | "devDependencies": { 60 | "@babel/core": "^7.6.4", 61 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 62 | "@babel/plugin-transform-runtime": "^7.6.2", 63 | "@babel/preset-env": "^7.6.3", 64 | "@babel/runtime": "^7.6.3", 65 | "babel-loader": "^8.0.6", 66 | "chalk": "^2.4.2", 67 | "copy-webpack-plugin": "^5.0.4", 68 | "cross-env": "^5.2.1", 69 | "css-loader": "^3.2.0", 70 | "file-loader": "^4.2.0", 71 | "framework7-component-loader": "^2.0.0", 72 | "html-webpack-plugin": "^3.2.0", 73 | "mini-css-extract-plugin": "^0.8.0", 74 | "optimize-css-assets-webpack-plugin": "^5.0.3", 75 | "ora": "^3.4.0", 76 | "postcss-loader": "^3.0.0", 77 | "postcss-preset-env": "^6.7.0", 78 | "rimraf": "^3.0.0", 79 | "style-loader": "^1.0.0", 80 | "uglifyjs-webpack-plugin": "^2.2.0", 81 | "url-loader": "^2.2.0", 82 | "webpack": "^4.41.1", 83 | "webpack-cli": "^3.3.9", 84 | "webpack-dev-server": "^3.8.2", 85 | "workbox-webpack-plugin": "^4.3.1" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-preset-env': {}, 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/.DS_Store -------------------------------------------------------------------------------- /src/css/app.css: -------------------------------------------------------------------------------- 1 | /* Custom color theme properties */ 2 | :root { 3 | --f7-theme-color: #FF6B22; 4 | --f7-message-sent-bg-color: #cddc39; 5 | } 6 | 7 | /* master detail width */ 8 | :root { 9 | --f7-page-master-width: 380px; 10 | } 11 | 12 | /* fix view-master tab width */ 13 | .tabbar-scrollable a.tab-link { 14 | width: 100%; 15 | flex-shrink: initial; 16 | } 17 | 18 | /* Your app custom styles here */ 19 | .view-master-detail .page-master-detail .link.back, 20 | .view-master-detail .navbar-master-detail .link.back { 21 | display: none; 22 | } 23 | 24 | /* Invert navigation bars to fill style */ 25 | :root, 26 | :root.theme-dark, 27 | :root .theme-dark { 28 | --f7-bars-bg-color: var(--f7-theme-color); 29 | --f7-bars-text-color: #fff; 30 | --f7-bars-link-color: #fff; 31 | --f7-navbar-subtitle-text-color: rgba(255,255,255,0.85); 32 | --f7-bars-border-color: transparent; 33 | --f7-tabbar-link-active-color: #fff; 34 | --f7-tabbar-link-inactive-color: rgba(255,255,255,0.54); 35 | --f7-searchbar-input-bg-color: #fff; 36 | --f7-sheet-border-color: transparent; 37 | --f7-tabbar-link-active-border-color: #fff; 38 | --f7-list-margin-vertical: 0; 39 | } 40 | .navbar, 41 | .toolbar, 42 | .subnavbar, 43 | .calendar-header, 44 | .calendar-footer { 45 | --f7-touch-ripple-color: var(--f7-touch-ripple-white); 46 | --f7-link-highlight-color: var(--f7-link-highlight-white); 47 | --f7-button-text-color: #fff; 48 | --f7-button-pressed-bg-color: rgba(255,255,255,0.1); 49 | } -------------------------------------------------------------------------------- /src/css/icons.css: -------------------------------------------------------------------------------- 1 | /* Material Icons Font (for MD theme) */ 2 | @font-face { 3 | font-family: 'Material Icons'; 4 | font-style: normal; 5 | font-weight: 400; 6 | src: url(../fonts/MaterialIcons-Regular.eot); 7 | src: local('Material Icons'), 8 | local('MaterialIcons-Regular'), 9 | url(../fonts/MaterialIcons-Regular.woff2) format('woff2'), 10 | url(../fonts/MaterialIcons-Regular.woff) format('woff'), 11 | url(../fonts/MaterialIcons-Regular.ttf) format('truetype'); 12 | } 13 | .material-icons { 14 | font-family: 'Material Icons'; 15 | font-weight: normal; 16 | font-style: normal; 17 | font-size: 24px; 18 | display: inline-block; 19 | line-height: 1; 20 | text-transform: none; 21 | letter-spacing: normal; 22 | word-wrap: normal; 23 | white-space: nowrap; 24 | direction: ltr; 25 | -webkit-font-smoothing: antialiased; 26 | text-rendering: optimizeLegibility; 27 | -moz-osx-font-smoothing: grayscale; 28 | font-feature-settings: 'liga'; 29 | } 30 | 31 | /* Framework7 Icons Font (for iOS theme) */ 32 | @font-face { 33 | font-family: 'Framework7 Icons'; 34 | font-style: normal; 35 | font-weight: 400; 36 | src: url("../fonts/Framework7Icons-Regular.eot"); 37 | src: url("../fonts/Framework7Icons-Regular.woff2") format("woff2"), 38 | url("../fonts/Framework7Icons-Regular.woff") format("woff"), 39 | url("../fonts/Framework7Icons-Regular.ttf") format("truetype"); 40 | } 41 | .f7-icons { 42 | font-family: 'Framework7 Icons'; 43 | font-weight: normal; 44 | font-style: normal; 45 | font-size: 28px; 46 | line-height: 1; 47 | letter-spacing: normal; 48 | text-transform: none; 49 | display: inline-block; 50 | white-space: nowrap; 51 | word-wrap: normal; 52 | direction: ltr; 53 | -webkit-font-smoothing: antialiased; 54 | text-rendering: optimizeLegibility; 55 | -moz-osx-font-smoothing: grayscale; 56 | -webkit-font-feature-settings: "liga"; 57 | -moz-font-feature-settings: "liga=1"; 58 | -moz-font-feature-settings: "liga"; 59 | font-feature-settings: "liga"; 60 | text-align: center; 61 | } 62 | -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/Framework7Icons-Regular.eot -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/Framework7Icons-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/Framework7Icons-Regular.woff -------------------------------------------------------------------------------- /src/fonts/Framework7Icons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/Framework7Icons-Regular.woff2 -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/MaterialIcons-Regular.eot -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/MaterialIcons-Regular.ttf -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/MaterialIcons-Regular.woff -------------------------------------------------------------------------------- /src/fonts/MaterialIcons-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/fonts/MaterialIcons-Regular.woff2 -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | hackernews7 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 |
38 | 39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/js/app.js: -------------------------------------------------------------------------------- 1 | import T7 from 'template7'; 2 | import Framework7 from 'framework7'; 3 | 4 | // import F7 components 5 | import Tabs from 'framework7/components/tabs/tabs.js'; 6 | import Toolbar from 'framework7/components/toolbar/toolbar.js'; 7 | import Infinitescroll from 'framework7/components/infinite-scroll/infinite-scroll.js'; 8 | 9 | // Install F7 Components 10 | Framework7.use([Tabs, Toolbar, Infinitescroll]); 11 | 12 | // Template7 helpers 13 | T7.registerHelper('pluralize', function (arr, options) { 14 | if (!arr) return ''; 15 | if (typeof arr === "number") return (arr < 2) ? options.hash.single : options.hash.multiple; 16 | return (arr.length === 1) ? options.hash.single : arr.length + " " + options.hash.multiple; 17 | }); 18 | // Template 7 Register partial 19 | T7.registerPartial( 20 | 'comments', 21 | '{{#each comments}}' + 22 | '
' + 23 | '
' + 24 | '
{{user}}, {{time_ago}}
' + 25 | '
' + 26 | '
{{content}}
' + 27 | '
' + 28 | '
' + 29 | '
' + 30 | '{{#if comments}}{{> "comments"}}{{/if}}' + 31 | '{{/each}}' 32 | ); 33 | 34 | // Import F7 Styles 35 | import 'framework7/css/framework7.bundle.css'; 36 | 37 | // Import Icons and App Custom Styles 38 | import '../css/icons.css'; 39 | import '../css/app.css'; 40 | 41 | // Import Routes 42 | import routes from './routes.js'; 43 | 44 | var app = new Framework7({ 45 | root: '#app', // App root element 46 | 47 | name: 'hackernews7', // App name 48 | theme: 'auto', // Automatic theme detection 49 | // App root data 50 | data() { 51 | return { 52 | apiUrl: "https://api.hnpwa.com/v0/", 53 | api: null 54 | } 55 | }, 56 | // App root methods 57 | methods: { 58 | fetchAPI() { 59 | var self = this; 60 | self.request.json(self.data.apiUrl, (api) => { 61 | self.data.api = api 62 | }) 63 | }, 64 | }, 65 | // App routes 66 | routes: routes, 67 | 68 | // Register service worker 69 | serviceWorker: { 70 | path: '/HackerNews7/service-worker.js', 71 | }, 72 | }); -------------------------------------------------------------------------------- /src/js/routes.js: -------------------------------------------------------------------------------- 1 | 2 | import AboutPage from '../pages/about.f7.html'; 3 | 4 | import NotFoundPage from '../pages/404.f7.html'; 5 | 6 | import StoriesPage from '../pages/stories.f7.html'; 7 | import StoryPage from '../pages/story.f7.html'; 8 | 9 | var routes = [ 10 | { 11 | path: '/', 12 | async: function (routeTo, routeFrom, resolve, reject) { 13 | var self = this; 14 | var app = self.app; 15 | 16 | // Get hnapi data 17 | if (app.data.api = JSON.parse(localStorage.getItem('hn7-api'))) { 18 | resolve({ 19 | component: StoriesPage, 20 | }) 21 | } else { 22 | app.request.json(app.data.apiUrl, function (data) { 23 | app.data.api = data; 24 | localStorage.setItem('hn7-api', JSON.stringify(data)); 25 | resolve({ 26 | component: StoriesPage, 27 | }) 28 | }) 29 | } 30 | }, 31 | master: true, 32 | detailRoutes : [ 33 | { 34 | path: '/story/:id/', 35 | component: StoryPage, 36 | }, 37 | ] 38 | }, 39 | { 40 | path: '/about/', 41 | component: AboutPage, 42 | }, 43 | { 44 | path: '/story/:id/', 45 | component: StoryPage, 46 | }, 47 | { 48 | path: '(.*)', 49 | component: NotFoundPage, 50 | }, 51 | ]; 52 | 53 | export default routes; -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hackernews7", 3 | "short_name": "hn7", 4 | "description": "Framework7 HackerNews web app", 5 | "lang": "en-US", 6 | "start_url": "/HackerNews7/", 7 | "display": "standalone", 8 | "background_color": "#FF6B22", 9 | "theme_color": "#FF6B22", 10 | "icons": [ 11 | { 12 | "src": "/static/icons/128x128.png", 13 | "sizes": "128x128", 14 | "type": "image/png" 15 | }, 16 | { 17 | "src": "/static/icons/144x144.png", 18 | "sizes": "144x144", 19 | "type": "image/png" 20 | }, 21 | { 22 | "src": "/static/icons/152x152.png", 23 | "sizes": "152x152", 24 | "type": "image/png" 25 | }, 26 | { 27 | "src": "/static/icons/192x192.png", 28 | "sizes": "192x192", 29 | "type": "image/png" 30 | }, 31 | { 32 | "src": "/static/icons/256x256.png", 33 | "sizes": "256x256", 34 | "type": "image/png" 35 | }, 36 | { 37 | "src": "/static/icons/512x512.png", 38 | "sizes": "512x512", 39 | "type": "image/png" 40 | } 41 | ] 42 | } -------------------------------------------------------------------------------- /src/pages/404.f7.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /src/pages/about.f7.html: -------------------------------------------------------------------------------- 1 | 29 | -------------------------------------------------------------------------------- /src/pages/stories.f7.html: -------------------------------------------------------------------------------- 1 | 49 | -------------------------------------------------------------------------------- /src/pages/story.f7.html: -------------------------------------------------------------------------------- 1 | 33 | -------------------------------------------------------------------------------- /src/service-worker.js: -------------------------------------------------------------------------------- 1 | // manifest import and workbox imports will be autogenerated by webpack 2 | workbox.precaching.precacheAndRoute(self.__precacheManifest || []); -------------------------------------------------------------------------------- /src/static/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/.DS_Store -------------------------------------------------------------------------------- /src/static/icons/128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/128x128.png -------------------------------------------------------------------------------- /src/static/icons/144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/144x144.png -------------------------------------------------------------------------------- /src/static/icons/152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/152x152.png -------------------------------------------------------------------------------- /src/static/icons/192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/192x192.png -------------------------------------------------------------------------------- /src/static/icons/256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/256x256.png -------------------------------------------------------------------------------- /src/static/icons/512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/512x512.png -------------------------------------------------------------------------------- /src/static/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/static/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/favicon.ico -------------------------------------------------------------------------------- /src/static/icons/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GuillaumeBiton/HackerNews7/625a54b5dc90372541b8e37c405f4eef0f3b5874/src/static/icons/favicon.png -------------------------------------------------------------------------------- /src/template7-helpers-list.js: -------------------------------------------------------------------------------- 1 | /* 2 | Put here array of custom Template7 helpers that you have registered in app. 3 | It is required for Template7 server-side precompilation 4 | 5 | For example: 6 | module.exports = ['custom-helper', 'formatDate']; 7 | */ 8 | module.exports = ['pluralize']; 9 | --------------------------------------------------------------------------------