├── .gitignore ├── .travis.yml ├── process ├── mockup.jpg └── devlog.md ├── .babelrc ├── screenshots ├── avatars.png ├── first-ui.png ├── GitHunt-add.png ├── GitHunt-app.png ├── GitHunt-new.png ├── error-stack.png ├── github-api.png ├── default-mock.png ├── useful-error.png ├── GitHunt-GraphQL.png ├── first-mutation.png ├── github-oath-setup.png └── github-oauth-keys.png ├── .eslintrc ├── ui ├── subscriptions.js ├── routes.js ├── style.css ├── Html.js ├── RepoInfo.js ├── client.js ├── NewEntry.js ├── server.js ├── Layout.js ├── Feed.js └── CommentsPage.js ├── webpack.config.js ├── webpack.production.config.js ├── LICENSE ├── README.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dev.sqlite3 4 | .env 5 | .idea/ 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | - "5" 5 | - "4" 6 | -------------------------------------------------------------------------------- /process/mockup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/process/mockup.jpg -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "stage-2", 5 | "react" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /screenshots/avatars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/avatars.png -------------------------------------------------------------------------------- /screenshots/first-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/first-ui.png -------------------------------------------------------------------------------- /screenshots/GitHunt-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/GitHunt-add.png -------------------------------------------------------------------------------- /screenshots/GitHunt-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/GitHunt-app.png -------------------------------------------------------------------------------- /screenshots/GitHunt-new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/GitHunt-new.png -------------------------------------------------------------------------------- /screenshots/error-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/error-stack.png -------------------------------------------------------------------------------- /screenshots/github-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/github-api.png -------------------------------------------------------------------------------- /screenshots/default-mock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/default-mock.png -------------------------------------------------------------------------------- /screenshots/useful-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/useful-error.png -------------------------------------------------------------------------------- /screenshots/GitHunt-GraphQL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/GitHunt-GraphQL.png -------------------------------------------------------------------------------- /screenshots/first-mutation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/first-mutation.png -------------------------------------------------------------------------------- /screenshots/github-oath-setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/github-oath-setup.png -------------------------------------------------------------------------------- /screenshots/github-oauth-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drFabio/GitHunt-React/master/screenshots/github-oauth-keys.png -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "mocha": true, 5 | }, 6 | "extends": "airbnb", 7 | "parser": "babel-eslint", 8 | "globals": { 9 | "ga": true 10 | }, 11 | "rules": { 12 | "camelcase": 0 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ui/subscriptions.js: -------------------------------------------------------------------------------- 1 | import { print } from 'graphql-tag/printer'; 2 | 3 | // quick way to add the subscribe and unsubscribe functions to the network interface 4 | export default function addGraphQLSubscriptions(networkInterface, wsClient) { 5 | return Object.assign(networkInterface, { 6 | subscribe(request, handler) { 7 | return wsClient.subscribe({ 8 | query: print(request.query), 9 | variables: request.variables, 10 | }, handler); 11 | }, 12 | unsubscribe(id: number) { 13 | wsClient.unsubscribe(id); 14 | }, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './ui/client.js', 3 | output: { 4 | filename: "bundle.js", 5 | publicPath: '/' 6 | }, 7 | module: { 8 | loaders: [{ 9 | test: /\.css/, 10 | loader: 'style!css' 11 | }, { 12 | test: /\.js$/, 13 | loader: 'babel', 14 | // Exclude apollo client from the webpack config in case 15 | // we want to use npm link. 16 | exclude: /(node_modules)|(apollo-client)/ 17 | }, { 18 | test: /\.json$/, 19 | loader: 'json' 20 | }] 21 | }, 22 | devServer: { 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /ui/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Route, IndexRoute } from 'react-router'; 3 | 4 | import Feed from './Feed'; 5 | import Layout from './Layout'; 6 | import NewEntry from './NewEntry'; 7 | import CommentsPage from './CommentsPage'; 8 | 9 | export default ( 10 | 14 | 17 | 21 | 25 | 29 | 30 | ); 31 | -------------------------------------------------------------------------------- /webpack.production.config.js: -------------------------------------------------------------------------------- 1 | const HtmlWebpackPlugin = require('html-webpack-plugin') 2 | const webpack = require('webpack'); 3 | 4 | module.exports = { 5 | devtool: 'cheap-module-source-map', 6 | entry: './ui/client.js', 7 | output: { 8 | path: 'api/dist/', 9 | publicPath: '/', 10 | filename: 'bundle.js' 11 | }, 12 | module: { 13 | loaders: [{ 14 | test: /\.css/, 15 | loader: 'style!css' 16 | }, { 17 | test: /\.js$/, 18 | loader: 'babel', 19 | exclude: /node_modules/ 20 | }, { 21 | test: /\.json$/, 22 | loader: 'json' 23 | }] 24 | }, 25 | plugins: [ 26 | new webpack.DefinePlugin({ 27 | 'process.env': { 28 | 'NODE_ENV': JSON.stringify('production') 29 | } 30 | }), 31 | new HtmlWebpackPlugin({ 32 | template: 'ui/index.html' 33 | }), 34 | new webpack.optimize.CommonsChunkPlugin('common.js'), 35 | new webpack.optimize.DedupePlugin(), 36 | new webpack.optimize.UglifyJsPlugin(), 37 | new webpack.optimize.AggressiveMergingPlugin() 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Meteor Development Group 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 | -------------------------------------------------------------------------------- /ui/style.css: -------------------------------------------------------------------------------- 1 | .media-vote { 2 | display: table-cell; 3 | vertical-align: top; 4 | padding-right: 10px; 5 | } 6 | .media-vote .btn-score { 7 | border: none; 8 | background-color: transparent; 9 | font-size: 1.3em; 10 | padding: 3px 12px; 11 | line-height: 0; 12 | color: rgba(91, 192, 222, 0.52); 13 | } 14 | .media-vote .btn-score:hover, .media-vote .btn-score.active { 15 | color: #5bc0de; 16 | box-shadow: none; 17 | } 18 | .media-vote .btn-score:active { 19 | color: #5BA2DE; 20 | box-shadow: none; 21 | } 22 | .media-vote .btn-score:focus { 23 | outline: none; 24 | } 25 | .media-vote .vote-score { 26 | text-align: center; 27 | font-size: 1.2em; 28 | } 29 | 30 | .invisible { 31 | visibility: hidden; 32 | } 33 | 34 | body { 35 | padding-bottom: 60px; 36 | } 37 | 38 | .comment-box { 39 | border-top:1px solid black; 40 | padding: 5px; 41 | } 42 | 43 | #footer { 44 | position: fixed; 45 | bottom: 0px; 46 | text-align: center; 47 | width: 100%; 48 | background-color: #f0f0f0; 49 | border-top: 1px solid #c4c4c4; 50 | padding-top: 10px; 51 | } 52 | 53 | #footer li { 54 | display: inline; 55 | margin: 40px 10px; 56 | color: #999; 57 | font-size: 13px; 58 | } 59 | -------------------------------------------------------------------------------- /ui/Html.js: -------------------------------------------------------------------------------- 1 | import React, { PropTypes } from 'react'; 2 | 3 | // XXX: production setup? 4 | const basePort = process.env.PORT || 3000; 5 | const scriptUrl = `http://localhost:${basePort + 20}/bundle.js`; 6 | 7 | function Html({ content, state }) { 8 | return ( 9 | 10 | 11 | 12 | 13 | 14 | GitHunt 15 | 16 | 17 |
18 | 24 |