<repo_name>easyCZ/hacker-news-react-native<file_sep>/app/api/HackerNews.js
import {fetch} from 'fetch';


let HACKER_NEWS_API_URL = "https://hacker-news.firebaseio.com";
let TOP_STORIES = '/v0/topstories.json';
let STORY = '/v0/item/';

class HackerNews {

    static topStories() {
        return fetch(HACKER_NEWS_API_URL + TOP_STORIES);
    }

    static article(id) {
      return fetch(HACKER_NEWS_API_URL + STORY + id + '.json');
    }

}

export default HackerNews;
<file_sep>/app/articles/ArticleListStyleSheet.js
import {StyleSheet} from 'react-native';
import {vw, vh, vmin, vmax} from 'react-native-viewport-units';


let ArticleListStyleSheet = StyleSheet.create({

  container: {
    marginTop: 54,
    flex: 1,
    backgroundColor: 'lightgrey'
  }

});

export default ArticleListStyleSheet;
<file_sep>/app/Router.js
import React, {NavigatorIOS, StyleSheet} from 'react-native';

import ArticleList from './articles/ArticleList';
import ArticleActions from './articles/ArticleActions';


let styles = StyleSheet.create({

  navigator: {
    flex: 1
  }

});


class Router extends React.Component {

  render() {

    let initialRoute = {
      title: 'HN - Top Stories',
      component: ArticleList,
      rightButtonTitle: 'Refresh',
      onRightButtonPress: () => ArticleActions.getArticles()
    };

    return (
      <NavigatorIOS
        style={styles.navigator}
        initialRoute={initialRoute}
        barTintColor="#ff6600"
      />
    );

  }

}

module.exports = Router;
<file_sep>/app/articles/ArticleList.js
import React, {ListView, Text} from 'react-native';
import ArticleListStyleSheet from './ArticleListStyleSheet';
import HackerNews from '../api/HackerNews';

import ArticleStore from './ArticleStore';
import ArticleActions from './ArticleActions';
import ArticleRow from './ArticleRow';



class ArticleList extends React.Component {

  constructor(props) {
    super(props);

    this.articlesDataSource = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2
    });
  }

  componentWillMount() {
    this.updateArticles();
  }

  componentDidMount() {
    ArticleStore.addArticlesChangeListener(this.updateArticles.bind(this));
    ArticleActions.getArticles();
  }

  componentWillUnmount() {
    ArticleStore.removeArticlesChangeListener(this.updateArticles.bind(this));
  }

  updateArticles() {
    console.log('Update articles', ArticleStore.getArticles());
    this.setState({
      articles: this.articlesDataSource.cloneWithRows(
        ArticleStore.getArticles().slice(0, 10))
    });
  }

  renderRow(rowData, sectionID, rowID, highlightRow) {
    console.log('highlight', rowData, sectionID, rowID, highlightRow);
    return (
      <ArticleRow
        articleId={rowData}
        highlightRowFn={highlightRow} />
    );
  }

  render() {

    if (!this.state) return (<Text>Loading...</Text>);

    return (
      <ListView
        dataSource={this.state.articles}
        initialListSize={10}
        renderRow={this.renderRow} />
    )

  }


}


module.exports = ArticleList;
<file_sep>/app/articles/ArticleRowStyleSheet.js
import {StyleSheet} from 'react-native';
import {vw, vh, vmin, vmax} from 'react-native-viewport-units';


let ArticleRowStyleSheet = StyleSheet.create({

  container: {
    flex: 1,
    flexDirection: 'row',
    height: 10 * vh,
    width: 100 * vw,
    alignItems: 'center',
    padding: 5,
    borderColor: 'orange'
    // justifyContent: 'center',
    // alignSelf: 'center'
  },

  score: {
    width: 5 * vw,
    height: 5 * vw,
    backgroundColor: 'white'
  }

});

export default ArticleRowStyleSheet;
<file_sep>/app/articles/ArticleStore.js
import AppDispatcher from '../AppDispatcher';
import events from 'events';


let _articles = [];
let _articleDetails = {};

class ArticleStore extends events.EventEmitter {

  constructor() {
    super();
  }


  getArticles() {
    return _articles;
  }

  setArticles(articles) {
    _articles = articles;
  }

  emitArticlesChange() {
    this.emit('ARTICLES_CHANGE', this.getArticles());
  }

  addArticlesChangeListener(callback) {
    this.on('ARTICLES_CHANGE', callback);
  }

  removeArticlesChangeListener(callback) {
    this.removeListener('ARTICLES_CHANGE', callback);
  }


  getArticle(id) {
    return _articleDetails[id];
  }

  setArticle(id, article) {
    _articleDetails[id] = article;
  }

  emitArticleChange(id) {
    this.emit('ARTICLE_CHANGE:' + id, this.getArticle(id))
  }

  addArticleChangeListener(id, callback) {
    this.on('ARTICLE_CHANGE:' + id, callback);
  }

  removeArticleChangeListener(id, callback) {
    this.removeListener('ARTICLE_CHANGE:' + id, callback);
  }

}

let articleStore = new ArticleStore();

AppDispatcher.register( ({action, source}) => {

  let {actionType, data} = action;

  switch (actionType) {

    case 'TOP_STORIES:LOADED':
      articleStore.setArticles(data);
      articleStore.emitArticlesChange();
      break;

    case 'TOP_STORY:LOADED':
      articleStore.setArticle(data.id, data);
      articleStore.emitArticleChange(data.id);
      break;

    default:
      return true;

  }

});

export default articleStore;
<file_sep>/app/articles/ArticleActions.js
import HackerNews from '../api/HackerNews';
import AppDispatcher from '../AppDispatcher';


let _onStoriesReceive = (stories) => {
  console.log('Received stories', stories);
  AppDispatcher.handleView({
    actionType: 'TOP_STORIES:LOADED',
    data: stories
  });
}

let _onStoriesFail = (error) => {
  console.log('Failed to get stories', error);
  AppDispatcher.handleView({
    actionType: 'TOP_STORIES:FAILED',
    data: error
  });
}

let _onStoryReceive = (story) => {
  console.log('Received story', story.id, story);
  AppDispatcher.handleView({
    actionType: 'TOP_STORY:LOADED',
    data: story
  });
}

let _onStoryFail = (id, error) => {
  console.log('Failed to fetch story #' + id, error);
  AppDispatcher.handleView({
    actionType: 'TOP_STORY:FAILED',
    data: error
  });
}

class ArticleActions {

  static getArticles() {
    HackerNews
      .topStories()
      .then(r => r.json(), e => _onStoriesFail(e))
      .then(stories => _onStoriesReceive(stories));
  }

  static getArticle(id) {
    HackerNews
      .article(id)
      .then(r => r.json(), e => _onStoryFail(id, e))
      .then(story => _onStoryReceive(story));
  }




}

export default ArticleActions;
<file_sep>/README.md
# hacker-news-react-native
React Native implementation of a Hacker News reader
as dasas das 
<file_sep>/index.ios.js
'use strict';

var React = require('react-native');
var {AppRegistry} = React;

var HackerNews = require('./dist/App');


AppRegistry.registerComponent('HackerNewsRCT', () => HackerNews);
